Skip to content
POST /v1/eventsRequest access
Get started

Set up Sieve in 5 minutes

Sieve decides whether each event in your app looks like fraud and tells you why. You send it events from your server; it answers in milliseconds. Use the Node.js SDK, or call the JSON API from any language.

  1. Create a workspaceOnce your workspace is set up (request access), sign in. Sieve sets your workspace’s country (Kenya or Nigeria, for example) when it creates it, and you can see it in Settings. The country decides your reporting currency, your reporting thresholds (e.g. CBK’s KES 1M line in Kenya, the NFIU’s NGN 5M currency-transaction line in Nigeria) and your suspicious-transaction report deadline. You start in test mode, so nothing you do affects real customers.
  2. Choose how Sieve actsAlert only always tells your app allow, while opening cases and alerting your team. It’s the safe way to see what Sieve catches. Alert and block returns block for high-confidence fraud so your app can stop it. You can switch any time in Settings.
  3. Copy your test keyIt looks like sv_test_…. We show it once and keep only a fingerprint, so store it as an environment variable on your server, e.g. SIEVE_KEY. Never put it in a mobile app or website.
  4. Install the SDKOn Node.js 18 or later, add the Node.js SDK. It has types, retries and idempotency keys built in, and no dependencies. In any other language, skip this step and POST JSON to /v1/events with Authorization: Bearer <key>, as in the cURL example below.
    Terminal
    npm install @sievefraud/node
  5. Ask Sieve before money leavesAdd one call in front of every withdrawal. That’s the minimum integration, and it already catches the new-account cash-out.
    Node.js
    // npm install @sievefraud/node
    import { Sieve } from '@sievefraud/node'
    
    const sieve = new Sieve('sv_test_…')
    
    // Before you release a payout, ask Sieve.
    const d = await sieve.events.create({
      type: 'payout.requested',
      customer_id: user.id,
      amount: 48000,
      destination: { type: 'mpesa', account: payout.phone },
    })
    
    if (d.decision === 'block') return res.status(403).json({ error: 'Payout held for review' })
    if (d.decision === 'review') await holdPayout(payout.id, d.reasons)
    cURL
    curl https://sievefraud.com/v1/events \
      -H "Authorization: Bearer sv_test_…" \
      -H "Content-Type: application/json" \
      -d '{
        "type": "payout.requested",
        "customer_id": "cus_1001",
        "amount": 48000,
        "destination": { "type": "mpesa", "account": "254712345678" }
      }'
    Node.js, Nigeria (NIP bank payout)
    // npm install @sievefraud/node
    import { Sieve } from '@sievefraud/node'
    
    const sieve = new Sieve('sv_test_…')
    
    // Before you release a payout, ask Sieve.
    const d = await sieve.events.create({
      type: 'payout.requested',
      customer_id: user.id,
      amount: 350000,
      currency: 'NGN',
      method: 'bank',                                   // NIP transfer
      destination: { type: 'bank', account: payout.nuban, bank_code: payout.bankCode },
      customer: { phone: user.phone, bvn: user.bvn },   // BVN: 11 digits, optional
    })
    
    if (d.decision === 'block') return res.status(403).json({ error: 'Payout held for review' })
    if (d.decision === 'review') await holdPayout(payout.id, d.reasons)
  6. Send the rest of the journeyFraud is a sequence. Tell Sieve when customers sign up, log in, change details and move money, and every rule and pattern switches on. Each is one line.
    The five events
    // 1. When someone signs up
    await sieve.events.create({
      type: 'customer.created',
      customer_id: 'cus_1001',
      customer: { name: 'Wanjiku Kamau', phone: '+254712345678', email: '[email protected]', kyc_level: 'basic' },
      device: { id: deviceId, ip: req.ip },
    })
    
    // 2. When they change something sensitive
    await sieve.events.create({
      type: 'customer.updated',
      customer_id: 'cus_1001',
      changes: ['phone'],                 // phone | email | payout_destination | password | pin | name …
      customer: { phone: '+254799000111' },
    })
    
    // 3. On every login (success or failure)
    await sieve.events.create({ type: 'login', customer_id: 'cus_1001', login: { success: true }, device: { id: deviceId, ip: req.ip } })
    
    // 4. On money moving in or out
    await sieve.events.create({
      type: 'transaction',
      customer_id: 'cus_1001',
      direction: 'in',                    // or 'out'
      amount: 12500, currency: 'KES', method: 'mpesa',
      counterparty: { phone: '+254722000333', name: 'John Otieno' },
    })
    
    // 5. Before releasing a withdrawal: the call that matters most
    const d = await sieve.events.create({
      type: 'payout.requested',
      customer_id: 'cus_1001',
      amount: 48000,
      balance: 48500,                     // optional, powers the account-drain rule
      destination: { type: 'mpesa', account: '254799000111' },
      device: { id: deviceId, ip: req.ip },
    })
  7. Act on the decisiondecision is what your app should do: allow, review (hold it for a human) or block. reasons tells you why in plain English, ready to show your support team.
  8. Tell your team, and go liveIn Settings → Notifications add an email or Slack channel. Add a webhook in Developers if your systems should react automatically. Turn on two-factor authentication, create a live key, and switch it in.
No code yet? In Developers → Quickstart, “Run the scenario” plays a real fraud story through your own rules so you can see a block before you integrate.

Checklist before going live

  • Payout and withdrawal calls go through Sieve, and your app honours review and block.
  • Sign-ups include the customer’s name, so they’re screened against sanctions and PEP lists.
  • Detail changes send customer.updated with changes. This powers the rules that catch takeovers.
  • Your team receives alerts, and someone owns the Cases queue.
  • You send feedback (or close cases) so Sieve learns what fraud looks like for you.