Skip to main content

Classify a customer's transactions

Send a business's bank transactions to Walker Street Data and get each one back categorised, with its counterparty and confidence scores.

Before you start​

  • An API key with the transactions:enrich scope (see Authentication). The Node.js, Python and C# snippets read it from the WSD_API_KEY environment variable.
  • The sandbox base URL: https://sandbox.walkerstdata.com.au.
  • The customer's 11-digit ABN and some transactions for one of their bank accounts.
  • Node.js snippets use the built-in fetch (Node 18+) and top-level await, so save them as an .mjs file. Python snippets use requests. C# snippets are .NET 8 top-level programs using HttpClient and System.Text.Json, with no extra packages.

Each step builds on the one before it: variables such as customer_id and job_id carry over.

1. Create the customer​

Create a customer from their ABN. The call is idempotent: if the ABN is already known, you get the existing customerId back, so it's safe to call every time.

curl -X POST "https://sandbox.walkerstdata.com.au/v1/customer" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "abn": "53004085616" }'
{
"data": {
"customerId": "524ba9bc-06e7-417e-bd54-b99785f5194a",
"abn": "53004085616"
},
"message": null
}

2. Submit the transactions​

Send one account's details plus its transactions. Amounts are signed: negative for money out, positive for money in. Add your own transactionId to each transaction if you have one; it comes back as suppliedId so you can match results to your records. See Submit transactions as JSON for every field and limit.

curl -X POST "https://sandbox.walkerstdata.com.au/v1/customer/524ba9bc-06e7-417e-bd54-b99785f5194a/transactions" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"bankName": "Commonwealth Bank",
"bsb": "062-000",
"accountNumber": "10234567",
"accountName": "ACME Business Pty Ltd",
"accountType": "Business Transaction Account",
"transactions": [
{
"transactionId": "txn-20250409-0001",
"transactionDate": "2025-04-09",
"amount": 13167.00,
"description": "Direct Credit 158824 ARNOTT'\''S BISCUIT 339820002916682025",
"balance": 33155.05
},
{
"transactionId": "txn-20250408-0002",
"transactionDate": "2025-04-08",
"amount": -122.18,
"description": "METRO BLACKTOWN SOUTH BLACKTOWN AU Card xx3880 Value Date: 04/04/2025",
"balance": 19988.05
}
]
}'

The API accepts the batch straight away and returns a job to track:

{
"data": {
"jobId": "3f9a6c2e-81d4-4b7a-a5e0-c7d219f4b863",
"status": "New",
"flow": "RawJson",
"totalReceivedTransactions": 2
},
"message": null
}

3. Wait for the job to finish​

Poll the job's status until it reaches a terminal state: Completed, CompletedWithErrors or Failed. Don't wait for Completed alone, as a job that finishes CompletedWithErrors still has usable results. Every few seconds is plenty; to avoid polling altogether, use a webhook.

curl "https://sandbox.walkerstdata.com.au/v1/jobs/3f9a6c2e-81d4-4b7a-a5e0-c7d219f4b863/status" \
-H "x-api-key: YOUR_API_KEY"
{
"data": {
"jobId": "3f9a6c2e-81d4-4b7a-a5e0-c7d219f4b863",
"status": "Completed",
"flow": "RawJson",
"totalReceivedTransactions": 2,
"totalProcessedTransactions": 2,
"totalDuplicateTransactions": 0,
"warnings": null
},
"message": null
}

A non-zero totalDuplicateTransactions usually means the batch was sent before. That's safe: duplicates aren't stored twice, and they're still linked to this job. See Jobs for the full lifecycle.

4. Fetch the classified transactions​

Read the customer's transactions, scoped to this job with jobId. Pass page and count to page through large results (see Pagination).

curl "https://sandbox.walkerstdata.com.au/v1/customer/524ba9bc-06e7-417e-bd54-b99785f5194a/transactions?jobId=3f9a6c2e-81d4-4b7a-a5e0-c7d219f4b863&page=1&count=100" \
-H "x-api-key: YOUR_API_KEY"

Each transaction keeps its original values and gains an enrichment block: a Level 1 category, a Level 2 sub-category and the Level 3 counterparty, each with a confidence score. The account details are returned once in accounts and referenced by accountId.

{
"data": {
"accounts": [
{
"accountId": "b3f1d8e2-6a47-4c95-8e1b-0f2a9c7d5e63",
"bsb": "062-000",
"accountNumber": "10234567",
"institutionName": "Commonwealth Bank",
"sourcedVia": "raw"
}
],
"transactions": [
{
"transactionId": "e41c7a90-2b6d-4f85-9e13-7ac5d8b02f6e",
"suppliedId": "txn-20250409-0001",
"accountId": "b3f1d8e2-6a47-4c95-8e1b-0f2a9c7d5e63",
"transactionDate": "2025-04-09",
"amount": 13167.0,
"description": "Direct Credit 158824 ARNOTT'S BISCUIT 339820002916682025",
"balance": 33155.05,
"state": "Posted",
"enrichmentSource": "Cypher",
"enrichment": {
"level1": { "value": "credit_sales", "confidence": "0.94" },
"level2": { "value": "credit_sales_invoices", "confidence": "0.91" },
"level3": {
"counterpartyName": "Arnott's Biscuits Limited",
"counterpartyABN": "53004085616",
"confidence": "0.87"
}
}
}
],
"totalCount": 2,
"currentPage": 1,
"pageSize": 100,
"totalPages": 1
},
"message": null
}

enrichment is null for a transaction that hasn't been enriched. The full list of Level 1 and Level 2 tags is available from GET /v1/configuration/tags.

What's next​