arrow-left

Only this pageAll pages
gitbookPowered by GitBook
1 of 55

Flash Payments Developer API

Loading...

Basics

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Accounts

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Moving funds

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

FX

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

COMPLIANCE

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Other

Loading...

Loading...

Master Balance

Query your master account balances

Paste this query to the GraphQL Playground

const bodyJSON = {
  operationName: "balances",
  variables: {
    currencies: ["AUD"],
  },
  query: `
query balances($currencies: [CurrencyIso3]) {
  balances(currencies: $currencies) {
    currency cleared pending
  }
}`,
};
query balances($currencies: [CurrencyIso3]){
  balances(currencies: $currencies) {
    currency
    cleared
    pending
  }
}
{
  "currencies": ["AUD"]
}

The cleared is the Primary balance you see on the Flash Connect website.

The pending balance is typically not shown on the Flash Connect interface because it's rather short lived. If your Pending balance is not 0 then you can see it right next to the Primary balance.

If you omit the currencies input argument then the query would return all the currency balances you have. Contact us to enable more than just the default AUD currency.

hashtag
Top up your UAT account balance

If you need to increase your UAT account balance please sign in to the Flash Connect website, open Deposits page, and click Send Test Deposit.

Virtual account numbers

Generate named Virtual Account Numbers (aka sub-clients) for your clients' for collection

The sub-client (aka merchant) feature allows you to create client accounts for deposit collection purposes. These virtual accounts can be issued to individuals, companies, or other organisations.

circle-info

Note: This feature is disabled by default. Contact us if you want it.

Each sub-client will receive a dedicated BSB and Vitrual Account Number (VAN) that you or your clients can use to accept and withdraw domestic AUD transfers within Australia.

circle-exclamation

IMPORTANT: Your Australian VAN will be restricted to local Australian transfers. For international payments (aka FX payments), we offer different solutions.

The account name is your sub-client's name. For companies - it's their tradingAsName or legalName. For individuals - it's their fullName (firstName + middleName + lastName).

If your Flash account has a multi-currency feature enabled, each of your sub-clients will also have access to virtual accounts in the selected currencies for which you hold balances.

All depositsarrow-up-right sent to your sub-client Virtual Account Numbers (VANs) are booked on your (master-client's) corresponding account balances. Sub-clients can't have their own balances.

You can disburse fundsarrow-up-right and make FX paymentsarrow-up-right on behalf of your sub-clients by providing the sub-client ID when you create withdrawals or payments. This sub-client record will then be used as the sender, linked to the transaction, and reported to the government.

Notifications via webhooks will provide important sub-client information as well.

Sub-client statuses

Sub-client VANs lifecycle

A sub-client lifecycle follows these stages.

A sub-client is created and has the temporary INITIATED status. At this stage, the request has been received and the system is currently processing it.

If processing is completed successfully, the sub-client automatically transitions to the ACTIVE. In this status, the sub-client is fully activated and approved.

If the sub-client requires manual compliance review, the sub-client moves from INITIATED to the temporary UNAPPROVED status. From this status it would eventually transition to either ACTIVE or FAILED_KYC. Typically, we can't disclose the exact reason of the KYC failure, while it mostly happens because we do not have risk appetite for your client.

You can deactivate the client (via API of Flash Connect), - it'd move from ACTIVE to DEACTIVATED. A sub-client in the DEACTIVATED status can be activated by you at any time, returning to ACTIVE.

At any point, a sub-client may be moved to DISABLED. In this status, the sub-client is disabled and cannot be enabled by you, and contacting support is required for further information.

Query sub-clients

hashtag
Available queries

hashtag
Query for a single sub-client

const bodyJSON = {
  variables: {
    id: "606d28675a2d931bc925fec2",
      input: {
        currencies: ["EUR","USD","HKD","CNY"],
      },
  },
  query: `
query ($id: ID!, $input: FundingAccountQueryInput!) {
  subClient(id: $id) {
    id fullName legalName tradingAsNam clientType status 
    primaryContact {
      firstName middleName lastName email dob mobile
    }
    address {
      building street suburb state country postcode
    }
    postalAddress {
      building street suburb state country postcode
    } 
    businessNumber bsb accountNo externalId
    fundingAccounts(input: $input) {
      iban accountNo bic currency externalReference
    }
  }
}`,
};

hashtag
Query for multiple sub-clients

hashtag
Query for multiple sub-clients with filters

{
  "data": {
    "balances": [
      {
        "currency": "AUD",
        "cleared": 3860,
        "pending": 0
      }
    ]
  }
}
query($id: ID!, $input: FundingAccountQueryInput!) {
  subClient(id: $id) {
    id
    fullName
    legalName
    tradingAsName
    clientType
    status
    primaryContact {
      firstName
      middleName
      lastName
      email
      dob
      mobile
    }
    address {
      building
      street
      suburb
      state
      country
      postcode
    }
    postalAddress {
      building
      street
      suburb
      state
      country
      postcode
    }
    businessNumber
    bsb
    accountNo
  	externalId
    fundingAccounts(input: $input) {
      iban
      accountNo
      bic
      currency
      externalReference
    }
  }
}
{ 
  "id": "606d28675a2d931bc925fec2",
  "input": {
    "currencies": ["EUR", "USD", "HKD", "CNY"] 
  }
}
{
  "data": {
    "subClient": {
      "id": "606d28675a2d931bc925fec2",
      "fullName": "ACME Corp",
      "legalName": "ACME Corp",
      "tradingAsName": null,
      "clientType": "COMPANY",
      "status": "ACTIVE",
      "primaryContact": {
        "firstName": "John",
        "middleName": null,
        "lastName": "Smith",
        "email": "[email protected]",
        "dob": "1980-12-12",
        "mobile": "+61 422 832 849"
      },
      "address": {
        "building": "25",
        "street": "Moore St",
        "suburb": "Waterloo",
        "state": "NSW",
        "country": "AU",
        "postcode": "2017"
      },
      "postalAddress": {
        "building": "25",
        "street": "Moore St",
        "suburb": "Waterloo",
        "state": "NSW",
        "country": "AU",
        "postcode": "2017"
      },
      "businessNumber": "91383840265",
      "bsb": "802919",
      "accountNo": "1066419",
      "externalId": "991188227733"
    }
  }
}
const bodyJSON = {
  variables: {
    input: {
    },
  },
  query: `
query ($input: SubClientQueryInput!) {
  subClients(input: $input) {   
    id fullName legalName clientType status businessNumber
    bsb accountNo externalId
  }
}`,
};  
query($input: SubClientQueryInput!){
  subClients(input: $input) {
    id
    fullName
    legalName
    clientType
    status
    businessNumber
    bsb
    accountNo
    externalId
    # any other set of properties
  }
}
 {
 "input": {
  }
}
{
  "data": {
    "subClients": [
      {
        "id": "5fb314cb9224595df522db61",
        "fullName": "Richard Smith",
        "legalName": null,
        "clientType": "INDIVIDUAL",
        "status": "ACTIVE",
        "businessNumber": null,
        "bsb": "802919",
        "accountNo": "1963041",
        "externalId": null
      },
      {
        "id": "60612f00a4d7dd5c96e37676",
        "fullName": "ABC Capital",
        "legalName": "ABC Co",
        "clientType": "COMPANY",
        "status": "ACTIVE",
        "businessNumber": "839399923932",
        "bsb": "802919",
        "accountNo": "1914920",
        "externalId": null
      }
    ]
  }
}
const bodyJSON = {
  variables: {
    input: {
      clientType: "INDIVIDUAL",
      status: "ACTIVE",
      firstName: "John",
      lastName: "Smith",
      address: { 
        country: "AU", 
      },
    },
  },
  query: `
query ($input: SubClientQueryInput!) {
  subClients(input: $input) {   
    id fullName clientType status 
    primaryContact {
      firstName lastName
    }
    address {
      country
    }
  }
}`,
};  
query($input: SubClientQueryInput!){
  subClients(input: $input) {
    id
    fullName
    clientType
    status   
    primaryContact {
      firstName
      lastName
    }
    address {
      country
    }
    # any other set of properties
  }
}
{   
# more filters available, see SubClientQueryInput in API schema
  "input": {
    "clientType": "INDIVIDUAL",
    "status": "ACTIVE",
    "firstName": "John",
    "lastName": "Smith",
    "address": { 
      "country": "AU" 
    }
  }
}
{
  "data": {
    "subClients": [
      {
        "id": "5fb314cb9224595df522db61",
        "fullName": "John Smith",
        "clientType": "INDIVIDUAL",
        "status": "ACTIVE",
        "primaryContact": {
          "firstName": "John",
          "lastName": "Smith"
        },
        "address": {
          "country": "AU"
        }
      }
    ]
  }
}

Create sub-clients

There are two types of sub-clients: company and individual.

For every company registered as a sub-client, there must be one contact person for individual data submitted. Ideally, the contact person should be a company director or have a similar role. Therefore, if you are creating a sub-client of the company type, we require you to provide extra details:

  • legalName - company legal name

  • businessNumber - company business number (e.g. ABN in Australia)

If the above fields are not set, the sub-client will be created as individual type.

circle-exclamation

This action creates a real account number. If you ever submit fake, unreal, testing, or incorrect data - you will be immediately blocked from Flash Payments services.

Please add all possible precautions, processes, staff training, warning messages, and validation checks to your system(s) before creating a sub-client.

Please follow our latest requirements for the proper sub-client data submission:

  1. Provide proper firstName , middleName, and lastName Please note that including the accurate middleName is essential for the account name matching capability of the Australian New Payments Platform (NPP) real-time digital payment network.

  2. Provide proper mobile number

  3. Provide proper dob : the person must be under 65 years of age

  4. Provide proper residential address including unit and street number. The sub-client address should correspond to your approved use case from the contract agreement. By default, you can only create local Australian sub-clients with an adequate address.street field provided. Any non-Australian entities will undergo extended due diligence based on their location and industry relevance for Flash Payments.

  5. Provide proper idDoc (type, docNumber, issuer (optional), issueDate (optional), expiryDate (optional), and country ) based on the sub-client contact person's address. For Australian residents, either a driver’s license or a passport is accepted. For non-Australian residents, only a passport is accepted as a document type.

  6. Sometimes, we ask our partners to provide “instructing institution” information, but only if you are creating this VAN on behalf of another financial institution. More about institutions . You may provide the ID of the already created institution via the field instructingInstitutionId or as a full object via the instructingInstitution field.

The above personal data submission requirements should be as equally followed for the company contact person, with the exception of address property, which can be a company address in this case.

To create a sub-client, you need to execute the createSubClient mutation as below. You can find the description of each field in the GraphQL API schema.

const bodyJSON = {
  variables: {
mutation($input: CreateSubClientInput!) {
  createSubClient(input: $input) {
    success
    code
    message
    subClient {
      id
      legalName
      businessNumber
      fullName
      clientType
      status
      primaryContact {
        firstName
        lastName
        email
        mobile
        dob
      }
      address {
        country
      }
      bsb
      accountNo
      externalId
      # more properties available, see API schema
    }
  }
}
{ 
  "input": {
    "legalName": "Chineese Tradings",
    "businessNumber": "330782000329701",
    "firstName": "John",
    "lastName": "Smith",
    "email": "[email protected]",
    "mobile": "+61422832849",
    "dob": "1979-05-12",
    "address": {
      "building": "25",
      "street": "Xihu Road, Yuexiu District",
      "suburb": "Guangzhou City",
      "state": "Guangdong Province",
      "postcode": "510030",
      "country": "CN"
    },
    "idDoc": {
      "type": "passport",
      "docNumber": "FF1948394",
      "issuer": "Australian Passport Office (APO)",
      "issueDate": "2000-01-01",
      "expiryDate": "2045-01-01",
      "country": "AU"     
    },
    "externalId": "991188227733"
  }
}
{
  "data": {
    "createSubClient": {
      "success": true,
      "code": "SUBCLIENT_CREATED",
      "message": "Sub-client was successfully created",
      "subClient": {
        "id": "606d28675a2d931bc925fec2",
        "legalName": "Chineese Tradings",
        "businessNumber": "330782000329701",
        "fullName": "John Smith",
        "clientType": "INDIVIDUAL",
        "status": "ACTIVE",
        "primaryContact": {
          "firstName": "John",
          "lastName": "Smith",
          "email": "[email protected]",
          "mobile": "+61 422 832 849",
          "dob": "1979-05-12"
        },
        "address": {
          "country": "CN"
        },
        "bsb": "802919",
        "accountNo": "1066419",
        "externalId": "991188227733"
      }
    }
  }
}

Disable, Activate and Update sub-clients

You can disable and activate sub-clients. Deposits sent to a disabled sub-client will no longer be booked against your balance.

hashtag
Disabling a sub-client

const bodyJSON = {
  variables: {
    input: "606128f24bf29139b2cf74ef",
  },
  query: `
mutation ($input: ID!) {
  disableSubClient(id: $input) {
    success code message 
    subClient {
      id status
    }
  }
}`,
};
mutation($input: ID!) {
  disableSubClient(id: $input) {
    success
    code
    message
    subClient {
      id
      status
    }
  }
}
{ 
   "input": "606128f24bf29139b2cf74ef"
}
{
  "data": {
    "disableSubClient": {
      "success": true,
      "code": "SUCCESS",
      "message": "Sub-client was successfully disabled",
      "subClient": {
        "id": "606128f24bf29139b2cf74ef",
        "status": "DISABLED"
      }
    }
  }
}

hashtag
Activating a sub-client

const bodyJSON = {
  variables: {
mutation($input: ID!) {
  activateSubClient(
{ 
   "input": "606128f24bf29139b2cf74ef"
}
{
  "data": {
    "activateSubClient": {
      "success": true,
      "code": "SUCCESS",
      "message": "Sub-client was successfully activated",
      "subClient": {
        "id": "606128f24bf29139b2cf74ef",
        "status": "ACTIVE"
      }
    }
  }
}

hashtag
Updating sub-clients

At this point, you can only update the externalId , address and postalAddress properties because each sub-client has a set of linked domestic and international Virtual Account Numbers to send and receive funds.

circle-info

Please note, that the updated address will be re-verified, so make sure to include all its components, even if some fields, like the country, remain unchanged.

hashtag
Updating sub-client externalId

const bodyJSON = { 
  variables: {
    id: "660fef8e1f3b5452bd6945ec",
    input: {
      externalId: "my_system_id_29f-ae0978b00d09e",
    },
  }, 
  query: `
mutation ($id: ID!, $input: UpdateSubClientInput!) {
  updateSubClient(id: $id, input: $input) {
    success code message
    subClient {
      id status externalId
    }
  }
}`,
};
mutation($id: ID!, $input: UpdateSubClientInput!) {
  updateSubClient(id: $id, input: $input) {
    success
    code
    message
    subClient {
      id
      status
      externalId
    }
  }
}
{ 
  "id": "660fef8e1f3b5452bd6945ec", 
  "input": {
    "externalId": "my_system_id_29f-ae0978b00d09e"
  }
}
{
  "data": {
    "updateSubClient": {
      "success": true,
      "code": "SUCCESS",
      "message": "Sub-client was successfully updated",
      "subClient": {
        "id": "660fef8e1f3b5452bd6945ec",
        "status": "ACTIVE",
        "externalId": "my_system_id_29f-ae0978b00d09e"
      }
    }
  }
}

hashtag
Updating sub-client address

const bodyJSON = { 
  variables: {
    id: "660fef8e1f3b5452bd6945ec",
    input: {
      adddress: {
        street: "456 New St",
        suburb: "Newtow",
        state: "VIC",
        postcode: "3220", 
        country: "AU",
      },
    },
  }, 
  query: `
mutation ($id: ID!, $input: UpdateSubClientInput!) {
  updateSubClient(id: $id, input: $input) {
    success code message
    subClient {
      id status externalId address {building street suburb state postcode country}
    }
  }
}`,
};
mutation($id: ID!, $input: UpdateSubClientInput!) {
  updateSubClient(id: $id, input: $input) {
    success
    code
    message
    subClient {
      id
      status
      externalId
      address {
        building 
        street
        suburb
        state
        postcode
        country
      }
    }
  }
}
{ 
  "id": "660fef8e1f3b5452bd6945ec", 
  "input": {
    "address": {
        "street": "456 New St",
        "suburb": "Newtow",
        "state": "VIC",
        "postcode": "3220",
        "country": "AU"
    }
  }
}
{
  "data": {
    "updateSubClient": {
      "success": true,
      "code": "SUCCESS",
      "message": "Sub-client was successfully updated",
      "subClient": {
        "id": "660fef8e1f3b5452bd6945ec",
        "status": "ACTIVE",
        "externalId": "my_system_id_29f-ae0978b00d09e",
        "address": {
          "building": null,
          "street": "456 New St",
          "suburb": "Newtow",
          "state": "VIC",
          "postcode": "3220",
          "country": "AU"
        }
      }
    }
  }
}

Query conversions

You can query all your past conversions

hashtag
Retrieving all your conversions

const bodyJSON = {
  variables: {
    input: {
    },
  },
  query: `
query ($input: ConversionQueryInput!) {
  conversions(input: $input) {   
    id fromCurrency toCurrency rate 
  }
}`,
};    
 query($input: ConversionQueryInput!) {
  conversions(input: $input) {
    id
    fromCurrency
    toCurrency
    rate
    # there are many other properties
  }
}
 {
  "input": { 
  }
}
{
  "data": {
    "conversions": [
      {
        "id": "6b04c62ec0bf606bf216ae21",
        "fromCurrency": "AUD",
        "toCurrency": "EUR",
        "rate": 0.71
      },
      {
        "id": "6b04c6bfc0bf606bf216af06",
        "fromCurrency": "AUD",
        "toCurrency": "USD",
        "rate": 0.70
      },
      {
        "id": "6b04c8e3c0bf606bf216b026",
        "fromCurrency": "EUR",
        "toCurrency": "AUD",
        "rate": 0.71
      }
    ]
  }
}

hashtag
Retrieving some of your conversions

const bodyJSON = {
  variables: {
query($input: ConversionQueryInput!) {
  conversions(
{
  "input": { 
    "statuses": "CONVERTED",
    "toCurrencies": ["EUR","USD"]
  }
}
{
  "data": {
    "conversions": [
      {
        "id": "6833ad9b4e94acce5d4a031b",
        "fromCurrency": "AUD",
        "toCurrency": "USD"
      },
      {
        "id": "678a18bb2879c374b378ee71",
        "fromCurrency": "AUD",
        "toCurrency": "EUR"
      }
    ]
  }
}

hashtag
Retrieving a single conversion by ID

const bodyJSON = {
  variables: {
    input: "6b04c62ec0bf606bf216ae21",
  },
  query: `
query ($input: ID) {  
  conversion(id: $input) {
    status createdAt fromAmount toAmount 
  }
}`,
};
query($input: ID) {
  conversion(id: $input) {
    status
    createdAt
    fromAmount
    toAmount
    # there are many other properties
  }
}
{
  "input": "6b04c62ec0bf606bf216ae21"
}
{
  "data": {
    "conversion": {
      "status": "CONVERTED",
      "createdAt": "2024-08-13T05:45:28.698Z",
      "fromAmount": 1000,
      "toAmount": 710.01
    }
  }
}

input: "606128f24bf29139b2cf74ef",
},
query: `
mutation ($input: ID!) {
activateSubClient(id: $input) {
success code message
subClient {
id status
}
}
}`,
};
id
:
$input
)
{
success
code
message
subClient {
id
status
}
}
}
input: {
statuses: "CONVERTED",
toCurrencies: ["EUR","USD"],
},
},
query: `
query ($input: ConversionQueryInput!) {
conversions(input: $input) {
id fromCurrency toCurrency rate
}
}`,
};
input
:
$input
)
{
id
fromCurrency
toCurrency
# there are many other properties
}
}
input: {
legalName: "Chineese Tradings",
businessNumber: "330782000329701",
firstName: "John",
lastName: "Smith",
email: "[email protected]",
mobile: "+61422832849",
dob: "1979-05-12",
address: {
building: "25",
street: "Xihu Road, Yuexiu District",
suburb: "Guangzhou City",
state: "Guangdong Province",
postcode: "510030",
country: "CN",
},
idDoc: {
type: "passport",
docNumber: "FF1948394",
issuer: "Australian Passport Office (APO)",
issueDate: "2000-01-01",
expiryDate: "2045-01-01",
country: "AU",
},
externalId: "991188227733",
},
},
query: `
mutation ($input: CreateSubClientInput!) {
createSubClient(input: $input) {
success code message
subClient {
id legalName businessNumber fullName clientType status
primaryContact {
firstName lastName email mobile dob
}
address {
country
}
bsb accountNo externalId
}
}
}`,
};
here

Payouts

Disburse your money to a third party bank account

You can create payouts via the createWithdrawal mutation.

You can retrieve your payouts via the withdrawals query.

Sometimes you'd need to understand the supported delivery methods using the availableDeliveryMethods query.

If you get instructed by another financial institution then you must submit their details too.

If the payouts didn't pass compliance we would reject it with a proper rejection code and descriptive message.

Deposit statuses

Deposit processing statuses

Upon detecting a deposit in a Flash Payments Virtual Account Number (VAN), we immediately record it as a deposit in our system.

The status of a successful deposit goes through the following lifecycle

INITIALISED->REVIEWING→CONFIRMED

If you choose to reject a deposit, its status goes through the following lifecycle instead:

INITIALISED->REVIEWING→CONFIRMED→REFUNDING→REFUNDED

circle-exclamation

The REVIEWING is an optional action by Flash Payments Compliance team. Occasionally we pick some transactions for extended AML/CT review. Most transactions do not ever get into the REVIEWING status.

If Flash Payments Compliance choose to reject a deposit, its status lifecycle goes through following stages:

INITIALISED→REVIEWING→REFUNDING→REFUNDED

Conversions

Convert between your multi-currency balances

If you use our multi-currency feature, you can exchange currency and convert fundsarrow-up-right between your master accounts in real-time.

Conversion fees are detailed in your contract and vary based on your use case and risk assessment.

Conversion statuses

The GraphQL schema defines statuses like this:

enum ConversionStatus {
    INITIALISED
    PENDING
    CONVERTED
    FAILED
    CANCELLED
}

The status of a conversion can be any of the following:

  • INITIALISED — A conversion record was created, but no further action has been taken. This status typically does not occur via the API.

  • PENDING — The conversion is in progress. This is the usual status immediately after creation.

  • CONVERTED — The conversion completed successfully. Your balances have been updated accordingly.

  • FAILED — An error occurred during the conversion. This is usually a temporary state.

  • CANCELLED — The conversion was not completed and has been cancelled. This action is typically performed by the Flash Payments operations team.

Required fields

Here is how to identify the mandatory input fields for your GraphQL queries and mutations.

Most documentation examples utilise typical GraphQL input data for successfully executing queries.

It's strongly encouraged that you always submit complete and accurate data, as this reduces our compliance team's reviewing efforts and, as a result, speeds up transactions and provides a great experience for your customers.

At the same time, we recognise that gathering complete customer information can be technically challenging, particularly regarding country-specific address details or account information. As a result, our API documentation emphasises the required input fields based on the principle of minimal necessity.

Please pay attention to the exclamation mark ( ! ) next to the field type in the API schema specification from the "Docs" section of our API Playground. Those are the required fields as it's demonstated on the screenshot below:

Please always verify that you have all required data to initiate a successful mutation or query.

FX Payments

Convert and send your balance as single instruction

What we call "FX Payment" is a fully orchestrated account to account delivery of any currency(-ies) we support. Typical examples:

  • You need to send from the EU to Australia. You would have a European virtual IBAN on your name. As soon as you deposit some EUR to it - you'll see a corresponding amount of AUD on your master balance in a matter of minutes, which you'll be able to use immediately.

  • You need to fund someone's overseas IBAN in Euros. You send us the AUD and give us the recipient's details either via API or via you FlashConnect back-office GUI. We orchestrate the rest.

You can create payments. using the createPayment mutation.

You can your payments with the payments query.

But before you need to understand the supported delivery methods using the query.

Rejection codes

How to handle a payout rejection

If your withdrawal is canceled (aka rejected) by our AML and Compliance team, you'll receive the webhook containing both a rejection code (rejectCode) and a manually written rejection reason (statusMessage). You can find the same two properties within the GraphQL type.

Here is a current list of all possible rejectCodes, but please note this list can be extended with time.

triangle-exclamation

Refund deposits

Return the funds back to the original sender

hashtag
Refund deposit by ID

Deposits

Explains how to accept deposits programmatically

After fully registering with us, you get a BSB and a dedicated Virtual Account Number (VAN).

circle-exclamation

IMPORTANT: Your Australian VAN will be restricted to local Australian transfers. For international payments (aka FX payments), we offer different solutions.

Every deposit to your VAN would increase your Flash Payments balance.

Every deposit can trigger a notification, keeping you informed in real time

Payment statuses

The GraphQL schema defines statuses like this:

The status of a payment can be any of the following:

Payment Statuses:

  • INITIALISING – a draft payment. It may or may not have all required information to be executed. Typically, this never happens through the API. Can be created via the under certain circumstances.

  • OPEN – The payment is in progress.

retrieve
availableDeliveryMethods
The deposit data includes the payment reference (we call it
externalReference
in this API).

By default, only you are permitted to make deposits. However, we can enable third-party deposits for your account upon request. Once enabled, your account number functions as a local collection account, allowing others to deposit funds on your behalf.

We can also enable the sub-client feature. It allows you to programmatically create client accounts with dedicated BSB and account number for transactional purposes. You can give these bank account details to your clients to accept deposits. Once funds arrive, we will increase your account balance, and you will see a deposit with sub-client information linked to it.

To browse your deposits, you can use our FlashConnectarrow-up-right interface.

circle-info

Tip. You can simulate and test a deposit with the FlashConnect tool in the UAT environment. Just go to the Deposits page and click "SEND TEST DEPOSIT". Additionally, you can test a deposit sent by your sub-client in the UAT. Just go to the Sub-clients page, find the sub-client, and click "SEND TEST DEPOSIT".

Webhooks
Please note: CANCELLED is a final status for any withdrawal. Please do not retry a withdrawal if it was rejected by our Compliance team or by a beneficiary financial institution.

Only those withdrawals rejected with code TECHNICAL_ISSUE may be re-submitted as new transactions.

Please also note that while the rejection codes are set, the corresponding free text statusMessage will have a case-by-case human written text explaining the root cause of the cancellation. We'll try to be as descriprive as possible taking into account the legal bounds (we are not allowed by the law to disclose certain information).

CANCELLATION_REQUESTED_BY_PARTICIPANT
CANCELLATION_BY_RECIPIENT_FI
COMPLIANCE_DECLINED
COMPLIANCE_DECLINED_EXTERNAL
SENDER_INADEQUATE_DATA
SENDER_INVALID_ADDRESS
SENDER_INCOMPLETE_ADDRESS
RECIPIENT_INADEQUATE_DATA
RECIPIENT_INVALID_ADDRESS
RECIPIENT_INCOMPLETE_ADDRESS
DATA_ENQUIRY_TIME_ELAPSED
DATA_ENQUIRY_RESPONSE_INADEQUATE
SOURCE_OF_FUNDS_INADEQUATE
DUPLICATE_TRANSACTION
TECHNICAL_ISSUE
RECIPIENT_ACCOUNT_CLOSED
RECIPIENT_INVALID_ACCOUNT_NUMBER
RECIPIENT_INVALID_BANK_CODE
RECIPIENT_INVALID_ACCOUNT
RECIPIENT_COUNTRY_NOT_SUPPORTED
RECIPIENT_CURRENCY_NOT_SUPPORTED
EXPIRED
withdrawal_cancelledarrow-up-right
withdrawal
const bodyJSON = {
  variables: {
    id: "6053d4e0e3bc655e0598a742",
    input: {
      amount: 10,
      reason: "sent by mistake",
    },
  }, 
  query: `
mutation ($id: ID!, $input: RefundDepositInput!) {
  refundDeposit(id: $id, input: $input) {
    success code message
  }
}`,
};
mutation($id: ID!, $input: RefundDepositInput!) {
  refundDeposit(id: $id, input: $input) {
    success
    code
    message
  }
}
  • CLOSED – The payment was successfully delivered.

  • FAILED – An error occurred during processing.

  • CANCELLED – The payment did not complete and was cancelled, usually by the Flash Payments operations team.

  • circle-info

    Important to understand that the Payment.history is a transfer logs and is not related to payment status at all. Sometimes the history may contain half a dozen entries, however your payment will go through only two steps: OPEN and CLOSED.

    enum PaymentStatus {
      INITIALISING
      OPEN
      CLOSED
      FAILED
      CANCELLED
    }
    Flash Payments apparrow-up-right
    { 
      "id": "6053d4e0e3bc655e0598a742",
      "input": { 
        "amount": 10, 
        "reason": "sent by mistake"
      }
    }
    {
      "data": {
        "refundDeposit": {
          "success": true,
          "code": "REFUND_SENT",
          "message": "Refund initiated successfully"
        }
      }
    }

    Overview

    Flash Payments Developer API documentation

    hashtag
    General information

    Flash Payments API is GraphQLarrow-up-right-based, offering simple and developer-friendly querying experience. All data is exchanged in JSON format.

    Flash Payments API playground is located here: https://api.uat.flash-payments.com.au/arrow-up-right

    hashtag
    Complete API docs

    This documentation website does not have full list of API fields and methods. This is intentional. The full list of the API calls you can performs and the data fields you can send/receive is listed in the (click "DOCS" on the right hand side).

    hashtag
    High level feature overview

    You can search, visualise, or extract your data using our interface.

    hashtag
    Instant local Australian deposit (aka pay-in)

    Once registration is complete, a dedicated BSB and Virtual Account Number (VAN) for use within Australia will be assigned to you.

    circle-exclamation

    IMPORTANT: Your Australian VAN will be restricted to local Australian transfers. For international payments (aka FX payments), we offer different solutions.

    Any funds deposited to your VAN would increase your Flash Payments balance. We store and retain the reference attached to each deposit (e.g., an invoice number) to support your reconciliation or reporting needs.

    By default, only you can deposit into your VAN. Third-party deposits are also supported, but this feature must be enabled separately

    Deposits are typically processed in real time, but depending on the bank, there may be a delay of up to 24 hours.

    You can configure webhook notifications to receive alerts for every deposit made to your VAN. Please visit to set up your deposit webhook.

    You can manually reject unwanted deposits via the interface. The funds will be returned to the original sender bank account.

    hashtag
    Local Australian withdrawal (aka pay-out)

    The Flash Payments API enables you to withdraw funds from your Flash Payments balance. By default, only you are authorized to receive these withdrawals. Third-party withdrawals (also known as payouts) are available upon request and require separate activation.

    If your payout involves a foreign exchange (FX) payment, it must be processed using the Australian Direct Entry system in accordance with legal requirements. Processing time may vary from immediate to a few hours. Other payouts are credited instantly.

    If a payout fails, you will receive a webhook notification detailing the reason for the failure.

    The payout remitter name is configurable. You can give us the remitter name as withdrawal.sender data property. This is especially useful for FX-linked payouts. If a Brazilian mama Katarina Oreiro sends money to her son in Australia, he will see his mom's name in the bank statement - "Payment from Katarina Oreiro".

    Payouts can also be done via the interface.

    hashtag
    Send or receive money internationally

    You can send your Flash Payments balance internationally via our API and benefit from instant delivery to many countries with local instant payment systems (e.g. Philippines)

    To initiate a payment, you must pre-create the sender and recipient via the API.

    All entities in our database, including withdrawals, payments, senders, and recipients, can store your system’s unique identifier. Please refer to the externalId field in the .

    Payment delivery times depend on the recipient's country. While many are processed quickly, some may take additional time. You’ll be notified via webhook whenever the payment status changes.

    You can send funds through an international payment to your Flash Payments account. A webhook notification will be triggered when we detect payments from other countries.

    hashtag
    Security

    The API token you generate expires in 4 hours. You can always use logout GraphQL mutation to expire it earlier.

    You can't reset your own password until we verify your identity.

    The interface supports Google and One-Time-Password logins.

    Webhooks have cryptographic signatures.

    IP address whitelisting feature is available from FlashConnect interface allowing login to our APIs from only preapproved addresses that you specify.

    API rate limiting is in place to ensure stable performance of our service and prevent its potential abuse.

    hashtag
    How to start

    1. Contact with us via or by clicking the Intercom button on the bottom right of this page.

    2. Explain what kind of services you are looking from Flash Payments.

    3. We will examine your needs and explain how to get access to our UAT environment.

    For more detailed instructions head to the page.

    hashtag
    Important notes

    hashtag
    Breaking changes

    While we will endeavour to not introduce any breaking changes they might still occur in the future. In that case we will communicate about the upcoming changes via your registered email.

    Ad hoc webhooks

    How to secure your callback endpoints

    When sending a payment, creating a local withdrawal or ordering a conversion you can provide us a webhook (callback) URI - callbackUri. We will call it when a payment or withdrawal status changes.

    We recommend API clients to generate and add ?signature=ASecretPerPaymentKey query to your callbackUri to make sure it's Flash Payments calling your webhook endpoint. For example:

    https://my-webhooks.example.com/flash-payments?signature=oZaDlmfXbdXSKCnuWrvos2ImVBFX2Ru5

    To avoid storing the signatures in a database we recommend generating them on the fly using a strong hash function or any kind of cryptography.

    hashtag
    Example

    circle-info

    This is just an example. Feel free to sign your URLs the way you want.

    You would need to implement two functions.

    1. Function to generate "signature".

    2. Function to verify the "signature".

    hashtag
    Generating signatures

    Node.js pseudo code to generate a signature in your integration code.

    The code above creates a callbackUri and externalId variables. Use both of them when creating a transfer in Flash Payments API.

    hashtag
    Verifying signatures

    Node.js pseudo code of your webhook HTTP request handler.

    Why GraphQL

    General information how to start using Flash Payments API

    circle-info

    hashtag
    Assumptions

    The examples below assume you are a verified customer of Flash Payments and have been enabled for API access.

    hashtag
    GraphQL Playground

    All the GraphQL queries can be sent via the or as a HTTP POST request to https://api.uat.flash-payments.com.au. Example:

    All the responses are JSON and have at least one property data and optional property errors.

    circle-info

    hashtag
    Tip

    In GraphQL Playground query editor press Cmd+Space or Ctrl+Space or Opt+Space or Alt+Space

    Some of the GraphQL query parameters are required, others are optional. To understand if a variable/property is required you would need to check the API schema.

    • Go to the and click the button "DOCS" on the right.

    • Browse through queries, mutations, input and output types. Find a variable/property which have an exclamation mark at the end. E.g. fromCurrency: FromCurrency!.

    • The exclamation mark denotes that the variable/property is mandatory.

    hashtag
    Data cleansing is your responsibility

    triangle-exclamation

    Do not ever send us "N/A" or "NA" or "NULL" or "null" or "nil" or any other dummy string values in any of the API fields.

    hashtag
    The user-agent HTTP header

    It is a good idea to always send custom user-agent HTTP header value when doing requests to Flash Payments API. Here is why:

    • In case of troubleshooting we will be able to trace and mitigate your support questions faster.

    • You might be blocked by our automated firewall if your user agent is something generic like curl, Java-http-client, python-requests, Ruby, etc.

    hashtag
    429 Too many requests

    Our API have smart monitoring and it may temporarily block your IP if it detects system misuse. For more information, please refer to the page.

    Statement

    Understand every movement of your primary balance

    This query returns the same data as the Download CSV button on the Account Statement page of the Flash Connectarrow-up-right.

    The dates must be any ISO 8601 formatted dates.

    const bodyJSON = {
      variables: {
    
    query($input: StatementQueryInput!) {
      statement(
    
    {
      "input": {
        "fromDate": "2023-08-28T00:00:00+03:00",
        "currency": "USD"
      }
    }
    {
      "data": {
        "statement": [
          {
            "success": true,
            "code": "GENERATED",
            "message": "Statement generated",
            "fromDate": "2023-08-27T21:00:00Z",
            "toDate": "2023-08-28T21:00:00Z",
            "rows": {
              [
                {
                  "debit": 123.45,
                  "credit": 0
                }
              ]
            }
          }
        ]
      }
    }

    The response dates are aways UTC. Timezones are always taken into account.

    Sending data as JSON

    Here is how to send your data to us as JSON instead of embedding it into the GraphQL queries.

    For your initial tests, it may be easier and more practical to send data by embedding values directly into the GraphQL queries and mutations, as shown in the example below.

    At the same time, to enable efficient and accurate handling of complex queries in code, we support sending GraphQL queries as JSON objects that consist of two properties: "query" and "variables". Here is how you can do it:

    • Declare the $input variable in the QraphQL "query"

    Adverse Media Search

    Screen individuals and organisations against adverse media sources

    Adverse Media Search (AMS) lets you screen an individual or organisation against web-based adverse media sources — news articles, court records, and other publicly available content.

    circle-info

    The feature is also available through the portal. You can perform the AMS directly from the UI, view your request history, and monitor usage statistics without writing any code. This can be useful for getting familiar with the feature before integrating it into your application via the API.

    You can via the adverseMediaSearch mutation or past searches via the amsRequest and

    input: {
    fromDate: "2023-08-28T00:00:00+03:00",
    currency: "USD",
    },
    },
    query: `
    query ($input: StatementQueryInput!) {
    statement(input: $input) {
    succes code message fromDate toDate
    rows {
    debit credit
    }
    }
    }`,
    };
    input
    :
    $input
    )
    {
    success
    code
    message
    fromDate
    toDate
    rows {
    debit
    credit
    # and many other fields
    }
    }
    }
    API Playgroundarrow-up-right
    FlashConnectarrow-up-right
    FlashConnectarrow-up-right
    FlashConnectarrow-up-right
    FlashConnectarrow-up-right
    API docsarrow-up-right
    FlashConnectarrow-up-right
    this pagearrow-up-right
    Basics
    amsRequests
    queries. Scans run in the background and can take several minutes. Use webhooks or poll the
    amsRequest
    query to track progress. See
    for the full lifecycle.
    Flash Connectarrow-up-right
    run a search
    AMS statuses
    or
    Shift+Space
    to show context help and possible options.
    GraphQL Playgroundarrow-up-right
    GraphQL Playgroundarrow-up-right
    Rate limitingarrow-up-right
    const secret = "abcdefg";
    function generateSignature(string) {
      return require("node:crypto")
        .createHmac("sha256", secret) // your secret key
        .update(string)
        .digest("base64");
    }
    
    const signature = generateSignature(stringIdFromMyDatabase);
    const callbackUri = 
      "https://my-webhooks.example.com/flashfx?signature=" + signature;
    const externalId = stringIdFromMyDatabase;
    
    // Use both callbackUri and externalId when creating transfers with Flash Payments API
    function myCallbackEndpointHandler(req, res) {
      const signature = req.query.signature;
      const stringIdFromMyDatabase = req.body.externalId;
      
      if (generateSignature(stringIdFromMyDatabase) !== signature) {
        console.error("Security warning! Webhook endpoint received bad data", req);
        res.sendStatus(500);
        return;
      }
      
      // continue with the webhook processing
    }
    echo '{
      "query":
        "{
           quote(input: {
             fromCurrency: AUD, toCurrency: USD, size: 9.9, currency: AUD
           })
           {
             bid ask symbol timestamp inverted
           }
         }"
    }' | curl -X POST 'https://api.uat.flash-payments.com.au' \
    -H 'authorization: Bearer YOUR_TOKEN' \
    -H 'content-type: application/json' \
    -d @-
    {
      "data": { ... },
      "errors": [ ... ]
    }
    string. The technology also requires you to declare the type of your input(s). See the
    QueryInput
    in the example below.
  • Provide the "variables" object with the "input" property. The value of it must be a JSON object structured exactly as the QueryInput type.

  • circle-exclamation

    Only include the top-level input argument in your GraphQL queries. Including additional types may lead to compatibility issues when schema changes are deployed in production.

    If you're using third-party tools or libraries to construct GraphQL queries, be aware that they may generate unsupported structures. We recommend avoiding GraphQL libraries to reduce this risk.

    Here is a screenshot of how a typical mutation looks like in the API Playground:

    Same request as cURL:

    echo '{
      "query":
        "{
           quote(input: {
             fromCurrency: AUD, toCurrency: USD, size: 9.9, currency: AUD
           })
           {
             bid ask symbol timestamp inverted
           }
         }"
    }' | curl -X POST 'https://api.uat.flash-payments.com.au' \
    -H 'authorization: Bearer YOUR_TOKEN' \
    -H 'content-type: application/json' \
    -d @-
    echo '{
      "query":
        "query ($input: QuoteInput!) {
           quote(input: $input) { bid ask symbol timestamp inverted }
         }",
      "variables": { 
        "input": { "fromCurrency": "AUD", "toCurrency": "USD", "size": 9.9, "currency": "AUD" }
      }
    }' | curl -X POST 'https://api.uat.flash-payments.com.au' \
    -H 'authorization: Bearer YOUR_TOKEN' \
    -H 'content-type: application/json' \
    -d @-
    echo '{
      "query":
        "mutation ($input: RecipientInput!) {
          createRecipient(input: $input) { code message recipient { id } }
        }",
      "variables": {
        "input": {
          "firstName": "Test",
          "lastName": "Lastest",
          "currency": "PHP",
          "accountIdType": "PH_CASH",
          "mobile": "+63 9121231234",
          "phCashoutNetwork": "MLHUILLIER",
          "address": {
            "building": "12th Floor Centerpoint Building",
            "street": "Julia Vargas Avenue corner Garnet Street",
            "suburb": "Pasig",
            "state": "manila",
            "country": "PH",
            "postcode": "1605"
          }
        }
      }
    }' | curl 'https://api.uat.flash-payments.com.au' \
    -H 'authorization: Bearer YOUR_TOKEN' \
    -H 'content-type: application/json' \
    -d @-

    Authentication

    Get your access token

    Before doing any other API calls you have to obtain an auth token. It's a standard JWT token carrying the following payload:

    {
      ...
    
      "iat": 1620967717,
      "exp": 1621054117
    }
    circle-info

    Tip: Use this handy website to parse the token contents: jwt.ioarrow-up-right

    The token lifetime is 4 hours at this time. We might change this value in the future.

    circle-exclamation

    Warning! You can't log in more than once per second. This limit is in place to maintain platform stability.

    To be more future-proof, it is recommended to parse the token payload and compare current time to the token's expiration time. JavaScript code:

    circle-exclamation

    This login mutation is a subject to change in the future.

    hashtag
    Getting a token

    1. After we enable you, go to the , click "DOCS" on the right to explore the possibilities.

    2. Find there the login mutation. Execute it to obtain your access token. For example: mutation { login(input: {email: "YOUR_EMAIL" password: "YOUR_PWD"}) {token message} }

    Here is an example of the login query.

    circle-exclamation

    We suggest always sending your queries and related data separately using the "QUERY VARIABLES" tab in the or programmatically by .

    If using then click the "HTTP HEADERS" on the bottom left and paste there the following (replace the YOUR_TOKEN with the value you have just received form the above mutation):

    hashtag
    Affiliation

    Clients that have contractual agreements with more than one subsidiary of Flash Payments, can use the optional field affiliation to control which account to log into.

    The affiliation field accepts one of two constant values - FP_AUS or FP_LUX - which are passed unquoted.

    If the affiliation value does not correspond to an existent account, authentication will fail with code UNREGISTERED even if an account exists with another affiliation and the credentials are correct.

    If the user has multiple affiliations and the field affiliation is omitted, authentication will fail with code NEED_AFFILIATION.

    Regular webhooks

    How to setup web hooks for your integration

    hashtag
    Event notifications with webhooks

    Flash Payments uses webhooks to notify your application when a transaction event happens in your account. This includes status update of your withdrawal, clearing of the incoming deposit, and more.

    With webhooks, you can subscribe to the events of interest to trigger a subsequent action within your integration.

    There are two steps to begin using webhooks. Building a custom endpoint on your server and registering it via the FlashConnectarrow-up-right settings.

    hashtag
    Building webhook endpoint

    Each time a transaction event happens, we will send a HTTP POST request to your endpoint(s) that are subscribed to that event. The payload with event data is in the JSON format and can be used immediately. Every webhook endpoint must acknowledge the request, and as we strongly advise, verify the webhook signature.

    Acknowledging request

    To acknowledge the receipt of the event, your endpoint must return 2xx HTTP status code. All other response codes, including 3xx codes, indicate that you did not receive the event.

    If we do not receive 200 HTTP status code, we will make up to 3 more request attempts. There is 6, 60 and 600 seconds delay between each delivery attempt respectively. If all request attempts fail, we mark webhook request as failed and will no longer try to deliver it.

    Each webhook request has a flashfx-request-id header with a string that uniquely identifies a webhook event. For example, if there are multiple delivery attempts for the webhook event, each request will hold the same flashfx-request-id. This can be used to check if the webhook event was already processed by your application.

    We advise that you acknowledge webhook request as early as possible.

    Securing the request

    To ensure that webhook was sent by Flash Payments and not a third party, we include the cryptographic signature in each request’s flashfx-signature header.

    Before you can verify a signature, you need to retrieve your endpoint’s secret from webhook settings in the . Each registered endpoint has a unique secret that is used to sign a payload delivered to you on each event. Steps to verify signature:

    1. Extract signature from the request header

    2. Compute HMAC with SHA256 function. Use your endpoint secret as key and JSON payload string as a message.

    3. Compare signature in the header to the computed signature.

    Here is a Node.js pseudo code to generate and compare signatures

    And verifying signature

    Testing your endpoint

    To make sure your webhook endpoint is setup correctly, you can make a test HTTP request from the webhook settings. Click the "Send Test” button. You should receive a dummy request, which will need to be acknowledged the same way as your real webhook requests.

    Then go to the history of the webhook requests and find the test request and response there.

    hashtag
    Subscribing to the events

    Webhook requests come with event data. You can see all available event types in the settings. To subscribe, select which events you would like to receive and specify your endpoint. Please note, your endpoint must adhere to the HTTPS protocol for security reasons.

    Convert funds

    Convert between your multi-currency balances

    To convert between, say, AUD and EUR you should:

    1. Request a tradeable quote with applicability: CONVERSION.

    2. Retrieve the quote ID from the response.

    3. Reference the quote ID when creating the conversion.

    Get a tradable quote ID:

    Convert funds:

    Query deposits

    hashtag
    Query all deposits

    const bodyJSON = {
      variables: {
    
    query($input: DepositQueryInput!) {
      deposits(
    
    { 
      "input": {
      }
    }
    {
      "data": {
        "deposits": [
          {
            "id": "6053d4e0e3bc655e0598a742",
            "amount": 2000,
            "currency": "AUD",
            "status": "CONFIRMED",
            "statusMessage": "Transaction Confirmed",
            "externalId": "PR.1vcl",
            "externalReference": "FX1111",
            "subClient": null,
            "createdAt": "2021-03-18T22:32:01.010Z"
          },
          {
            "id": "6053d3319588389e1443587e",
            "amount": 40,
            "currency": "AUD",
            "status": "CONFIRMED",
            "statusMessage": "Transaction Confirmed",
            "externalId": "PR.1vci",
            "externalReference": "FX2121",
            "subClient": {
              "id": "5fb314cb9224595df522db61",
              "fullName": "John Doe",
              "status": "ACTIVE",
              "clientType": "INDIVIDUAL"
            },
            "createdAt": "2021-03-18T22:24:49.096Z"
          },
        ]
      }
    }

    hashtag
    Query deposit by ID

    Withdrawal statuses

    Withdrawal processing statuses

    1. You create a withdrawal. Your balance goes down by the withdrawal amount plus fee. INITIALISED

      1. We might internally review the transaction. INITIALISED-> REVIEWING

      2. If review goes well it will become pending. REVIEWING→ PENDING

      3. Otherwise it gets cancelled. REVIEWING→ CANCELLED

    2. The transaction is sent to the recipient bank for processing. INITIALISED → PENDING

    3. PENDING →

      • CONFIRMED - the recipient bank has the money now. Does not mean the beneficiary account number was credited though. Mostly FINAL status. Except when bank decides to return the funds, the withdrawal gets refunded (see step 4).

    4. The recipient bank decided to return this transaction back to Flash Payments.CONFIRMED → FAILED → REFUNDED - usual way - automatic refunding. Your balance goes up by the withdrawal amount, Flash Payments keeps the fee. FINAL status.

    circle-exclamation

    The REVIEWING is an optional action by Flash Payments Compliance team. Occasionally we pick some transactions for extended AML/CT review. Most transactions do not ever get into the REVIEWING status.

    hashtag
    Most common status transitions

    hashtag
    Happy path

    INITIALISED→REVIEWING→PENDING→CONFIRMED

    hashtag
    Unhappy paths

    Recipient bank accepts the payout but then returns it:

    INITIALISED→PENDING→CONFIRMED→FAILED→REFUNDED

    Recipient bank rejects the payout:

    INITIALISED→PENDING→FAILED→REFUNDED

    Flash Payments Compliance team rejects the payout:

    INITIALISED→REVIEWING→CANCELLED

    hashtag
    Testing/simulating unhappy paths

    Typically, you want to adapt your system to handle the following common withdrawal scenarios:

    hashtag
    1. Too long in the REVIEWING status

    If your withdrawal is in this status this means that we are doing an internal review of it. It happens occasionally when you trigger our monitoring rules. Also, this means that we have sent your Compliance Team (or else) an email message requesting more information. You must respond. In other words, if there is a delay - it's on you. Because Flash Payments delivers all your transactions in real-time 24/7.

    circle-info

    Please always provide accurate and information, including the full address, to prevent delays associated with internal compliance reviews on our side.

    Sender and recipient addresses are automatically validated when a transaction is created. If the address cannot be verified, the transaction will be flagged for review by our Compliance team, resulting in processing delays. To help ensure smooth and timely processing, please provide complete and accurate address details.

    You can simulate the behaviour. Your externalReference must include this text: HALT_AML. For example: "testing HALT_AML attempt 2". The withdrawal will get stuck in REVIEWING forever.

    hashtag
    2. Fails AML and gets cancelled

    We checked the data you sent us for withdrawal. We didn't like it. So we cancel it immediately.

    You can simulate the behaviour. Your externalReference must include this text: FAIL_AML. For example: "testing FAIL_AML attempt 4". The withdrawal will be cancelled next moment after you submit it.

    hashtag
    3. Passes AML and gets processed

    If our smart AML/TM checks stop your withdrawal for manual review, you can have it automatically pushed forward by including PUSH_AML in the externalReference. For example: "testing PUSH_AML attempt 5". This enables the transaction to continue as if it were approved by the compliance analyst. It can be particularly useful during your integration testing activities and also help with UAT regression testing later.

    Please note that the REVIEWING status for this payout will be recorded on our end, and a withdrawal_reviewing webhook will be sent.

    hashtag
    4. Recipient bank rejects the money

    A common scenario in the Australian domestic payment system involves a transaction that appears successful initially, but is later reversed by the recipient’s bank—sometimes days after processing. This can happen for various reasons, such as an invalid or closed account number, an account in the wrong currency, or other account-related issues.

    You can simulate the behaviour. Your externalReference must include this text: FAIL_ACC. For example: "testing FAIL_ACC attempt 8". The withdrawal will be completed, and next moment failed and refunded.

    Delivery methods

    Different countries support different account types, transfer mechanisms, payment delivery methods.

    Please verify that you have all the required data to initiate a successful payment transfer.

    hashtag
    List all the available payment delivery methods

    const bodyJSON = {
      variables: {
    
    query($input: AvailableDeliveryMethodsInput!) {
      availableDeliveryMethods
    
    { 
      "input": {
      }
    
    {
      "data": {
        "availableDeliveryMethods": [
          {
            "country": "AE",
            "currency": "AED",
            "method": "ACC_NO",
            "requiredFields": [
              "bic",
              "accountNo"
            ]
          },
          {
            "country": "AT",
            "currency": "EUR",
            "method": "IBAN",
            "requiredFields": [
              "bic",
              "iban"
            ]
          },
    ...

    The response above means that if you want to send euros to Austria (AT) then you'd need a BIC (aka SWIFT) code and an IBAN.

    hashtag
    List some of the delivery methods

    The response above means that to send euros to France (FR) you have to have ether of:

    • BIC and an account number, or

    • BIC and an IBAN.

    Institutions

    CRUD queries for Institutions

    hashtag
    Instructing Institution

    Institution entity is a piece of information about the party who instructed you to make the withdrawal. This data is important for compliance within Australia. This is not the sender. If there is no other institution who has instructed this withdrawal, leave this blank and your own details will be used for compliance and auditing purposes.

    Institution explanation

    hashtag
    Creating institutions

    • via Flash Connect (you can copy an ID of an existing Institution).

    • via API by invoking createInstitution mutation.

    • by providing instructingInstitution object into createWithdrawal

    circle-exclamation

    Please avoid creating multiple Institutions for the same organisation because they are used for compliance reporting and subject to review.

    circle-info

    Before creating or updating an institution we will try to find an existing one by:

    • By instructingInstitution.externalId

    hashtag
    Creating institution example

    Confirmation of Payee

    Verify that a payee's account name matches their bank account details

    Confirmation of Payee (CoP) is a security feature that verifies whether an account holder's name matches the account details you provide. It helps to:

    • Reduce fraud by verifying the account holder's name before sending funds

    • Prevent accidental payments to wrong accounts due to mistyped details

    Query payments

    hashtag
    Retrieving all your payments

    CoP response codes

    Here is the list of all possible CoP response codes.

    Code
    Description
    Recommended Action

    Reference data

    1. - query bank information to validate if we support your BSB, IBAN, BIC (aka Swift code).

    2. depositDetails - query the accounts you can send deposits to in order to increase your Flash Payments master balance.

    FAILED - NOT FINAL status. Depending on the processing error we have three scenarios now.
    • REFUNDED - see step 4 below.

    • CANCELLED - manual action. Your balance goes up by the amount, Flash Payments keeps the fee. FINAL status.

    • PENDING - rare case - retrying. Sometimes it might work. Go to item 3.

    senderarrow-up-right
    recipientarrow-up-right
    availableDeliveryMethods - query countries/currency combinations we support and what the required bank account details are.
  • Rejection codes - Flash proprietary list of all the reasons why your payout could have been cancelled.

  • bankInfo

    Warn the user; consider proceeding with caution.

    NOT_MATCH

    The account name does not match the provided information.

    Alert the user. Verify the account details before proceeding.

    ACCOUNT_CLOSED

    The specified account is closed.

    Do not proceed. The recipient should provide alternative account details.

    ACCOUNT_NOT_FOUND

    The specified account cannot be found.

    Verify the BSB and account number are correct.

    ACCOUNT_TYPE_NOT_SUPPORTED

    The accountIdType provided is not yet supported for CoP checks.

    Fall back to manual verification if needed.

    COP_PLATFORM_ERROR

    An error occurred in the CoP platform, or the account has opted out from CoP.

    You may proceed with the payment at your own discretion.

    COP_LIMIT_EXCEEDED

    Your CoP request limit has been exceeded.

    Contact Flash Payments support.

    MATCH

    The account name exactly matches the provided information.

    Safe to proceed with payment.

    CLOSE_MATCH

    The account name partially matches. This may indicate a minor spelling difference or an abbreviated name.

    Click the "HTTP HEADERS" on the bottom and add this: {"authorization": "Bearer YOUR_TOKEN"}. Replace the YOUR_TOKEN with the token you just got.
  • Execute any other queries.

  • API Playgroundarrow-up-right
    API playgroundarrow-up-right
    submitting the variables as JSONarrow-up-right
    API Playgroundarrow-up-right
    FlashConnectarrow-up-right
    FlashConnectarrow-up-right
    FlashConnect arrow-up-right
    const bodyJSON = {
      variables: {
        input: {
          fromCurrency: "AUD",
          toCurrency: "EUR",
          size: "10000",
          currency: "AUD",
          tradeable: true,
          applicability: "CONVERSION",
        },
      },
      query: `
    query ($input: QuoteInput!) {
      quote(input: $input) {
        id bid ask symbol timestamp inverted expireAt
      }
    }`,
    };
    query($input: QuoteInput!) {
      quote(input: $input) {
        id
        bid
        ask
        symbol
        timestamp
        inverted
        expireAt
      }
    }
    input: {
    },
    },
    query: `
    query ($input: DepositQueryInput!) {
    deposits(input: $input) {
    id amount currency status statusMessage externalId externalReference
    subClient {
    id fullName status clientType
    }
    createdAt
    }
    }`,
    };
    input
    :
    $input
    )
    {
    id
    amount
    currency
    status
    statusMessage
    externalId
    externalReference
    subClient {
    id
    fullName
    status
    clientType
    }
    createdAt
    # more fields available, see API schema
    }
    }
    const bodyJSON = {
      variables: {
        input: "6053d4e0e3bc655e0598a742",
      },
      query: `
    query ($input: ID) {  
      deposit(id: $input) {
        id 
        amount currency status statusMessage externalId externalReference createdAt
      }
    }`,
    };
    query($input: ID) {
      deposit(id: $input) {
        id
        amount
        currency
        status
        statusMessage
        externalId
        externalReference
        createdAt
        # more fields available, see API schema
      }
    }
    input: {
    },
    },
    query: `
    query ($input: AvailableDeliveryMethodsInput!) {
    availableDeliveryMethods(input: $input) {
    country currency method requiredFields
    }
    }`,
    };
    (
    input
    :
    $input
    )
    {
    country
    currency
    method
    requiredFields
    }
    }
    }
    const bodyJSON = {
      variables: {
        input: {
          country: "FR",
          currency: "EUR",
        },
      }, 
      query: `
    query ($input: AvailableDeliveryMethodsInput!) {
      availableDeliveryMethods(input: $input) {
        country currency method requiredFields
      }
    }`,
    };
    query($input: AvailableDeliveryMethodsInput!) {
      availableDeliveryMethods(input: $input) {
        country
        currency
        method
        requiredFields
      }
    }
    mutation.
    By
    instructingInstitution.businessNumber
    AND
    instructingInstitution.address.country
  • By instructingInstitution.legalName AND instructingInstitution.address.country

  • const seconds = JSON.parse(Buffer.from(token.split(".")[1], "base64url")).exp;
    if (Date.now() >= seconds*1000) {
      // get new token
    }
    const bodyJSON = {
      variables: {
        input: {
          email: "[email protected]",
          password: "12345678",
        },
      },
      query: `
    mutation ($input: LoginInput!) {
      login(input: $input) {
        token message code success
      }
    }`,
    };
    mutation($input: LoginInput!) {
      login(input: $input) {
        token
        message
        code
        success
      }
    }
    {
      "input": { 
        "email": "[email protected]", 
        "password": "12345678" 
      }
    }
    {
      "data": {
        "login": {
          "token": "YOUR_TOKEN",
          "message": "OK",
          "code": "SUCCESS",
          "success": true
        }
      }
    }
    {
      "authorization": "Bearer YOUR_TOKEN"
    }
    {
      "input": { 
        "email": "[email protected]", 
        "password": "12345678",
        "affiliation": FP_AUS 
      }
    }
    const secret = "my-webhook-secret";
    function generateSignature(string) {
      return require("node:crypto")
        .createHmac("sha256", secret) // your secret key
        .update(string)
        .digest("base64");
    }
    function myCallbackEndpointHandler(req, res) {
      const signature = req.headers["flashfx-signature"];
      const payload = req.body;
      
      if (generateSignature(payload) !== signature) {
        console.error("Security warning! Webhook endpoint received bad data", req);
        res.sendStatus(500);
        return;
      }
      
      // proceed with the webhook processing
    }
    {
      "input": { 
        "fromCurrency": "AUD", 
        "toCurrency": "EUR", 
        "size": "10000", 
        "currency": "AUD",
        "tradeable": true,
        "applicability": "CONVERSION"
      }
    }
    {
      "data": {
        "quote": {
          "id": "685369cf85f7cb51fb4ae2eb",
          "bid": 0.55663,
          "ask": 0.57153,
          "symbol": "AUDEUR",
          "timestamp": "2025-06-19T01:37:19.418Z",
          "inverted": false,
          "expireAt": "2025-06-19T01:39:19.419Z"
        }
      }
    }
    const bodyJSON = {
      variables: {
        input: {
            note: "for major client",
            externalId: "561402",
            quoteId: "6854dcffaa36ba8534d5f8e2",
            callbackUri: "https://example.com/my-webhook/endpoint/",
        },
      },
      query: `
    mutation ($input: ConversionInput!) {
      createConversion(input: $input) {    
        success code message 
        conversion { 
          id fromCurrency toCurrency currencyPair fromAmount toAmount rate note 
          status statusMessage callbackUri externalId createdAt updatedAt 
        }
      }
    }`,
    };
    mutation($input: ConversionInput!) {
      createConversion(input: $input) {
        success code message
        conversion {
          id fromCurrency toCurrency currencyPair fromAmount toAmount rate note
          status statusMessage callbackUri externalId createdAt updatedAt
        }
      }
    }
    {
      "input": { 
        "note": "for major client",
        "externalId": "561402",
        "quoteId": "6854dcffaa36ba8534d5f8e2",
        "callbackUri": "https://example.com/my-webhook/endpoint/"
      }
    }
    {
      "data": {
        "createConversion": {
          "success": true,
          "code": "CREATED",
          "message": "Conversion successfully created",
          "conversion": {
            "id": "6711f0a7b549a701ebeb02ac",
            "fromCurrency": "EUR",
            "toCurrency": "AUD",
            "currencyPair": "AUDEUR",
            "fromAmount": 101,
            "toAmount": 159.81,
            "rate": 0.63199,
            "note": "for major client",
            "status": "PENDING",
            "statusMessage": "Awaiting execution",
            "callbackUri": "https://example.com/my-webhook/endpoint/",
            "externalId": "561402",
            "createdAt": "2024-10-18T05:22:47.433Z",
            "updatedAt": "2024-10-18T05:22:47.433Z"
          }
        }
      }
    }
    {
      # there are more query parameters available, see the API schema
      "input": "6053d4e0e3bc655e0598a742"
    }
    {
      "data": {
        "deposit": {
          "id": "6053d4e0e3bc655e0598a742",
          "amount": 2000,
          "currency": "AUD",
          "status": "CONFIRMED",
          "statusMessage": "Transaction Confirmed",
          "externalId": "PR.1vcl",
          "externalReference": "KX23249",
          "createdAt": "2021-03-18T22:32:01.010Z"
        }
      }
    }
    {
      "input": {
        "country": "FR", 
        "currency": "EUR" 
      }
    }
    {
      "data": {
        "availableDeliveryMethods": [
          {
            "country": "FR",
            "currency": "EUR",
            "method": "ACC_NO",
            "requiredFields": [
              "bic",
              "accountNo"
            ]
          },
          {
            "country": "FR",
            "currency": "EUR",
            "method": "IBAN",
            "requiredFields": [
              "bic",
              "iban"
            ]
          }
        ]
      }
    }
    const bodyJSON = {
      variables: {
        input: {
          legalName: "Intermediate Institution Ltd",
          businessNumber: "A39477669937",
          address: {
            postcode: "2000",
            street: "203 Business Street",
            country: "AU",
            state: "NSW",
            suburb: "Sydney",
        },
      },
    },
    query: `
    mutation ($input: InstitutionInput!) {
      createInstitution(input: $input) {
        success code message    
        institution {     
          id    
        }  
      }
    }`,
    };
    mutation($input: InstitutionInput!) {
      createInstitution(input: $input) {
        success
        code
        message
        institution {
          id
        }
      }
    }
     "input": {
        "legalName": "Intermediate Institution Ltd",
        "businessNumber": "A39477669937",
        "address": {
          "postcode": "2000",
          "street": "203 Business Street",
          "country": "AU",
          "state": "NSW",
          "suburb": "Sydney"
        }
      }
    }
    {
      "data": {
        "createInstitution": {
          "success": true,
          "code": "INSTITUTION_CREATED",
          "message": "Institution created",
          "institution": {
            "id": "65570da4f176682c5e412552"
          }
        }
      }
    }
    Provide confidence that money is being sent to the intended recipient
  • Alert you when the account name doesn't match or only partially matches

  • circle-info

    The feature is also available through the Flash Connectarrow-up-right portal. You can perform CoP checks directly from the UI, view your request history, and monitor usage statistics without writing any code. This can be useful for manual verification workflows or for getting familiar with the feature before integrating it into your application via the API.

    hashtag
    Making a CoP Request

    To verify account details, execute the confirmationOfPayee mutation. You must provide the accountIdType, the relevant account details, and the accountName you wish to verify.

    const bodyJSON = {
      variables: {
    
    mutation ($input: CopInput!) {
      confirmationOfPayee
    
     {
      "input": {
        "accountIdType": "BSB",
        "bsb": "012003",
        "accountNo": "123456789",
        "accountName": "John Smith"
      }
    }
    {
      "data": {
        "confirmationOfPayee": {
          "success": true,
          "code": "MATCH",
          "message": "Account name matches",
          "billable": true
        }
      }
    }

    The code field in the response indicates the result of the verificationarrow-up-right.

    The billable field indicates whether the CoP request may be subject to a fee.

    circle-info

    CoP requests are billed based on your agreement with Flash Payments. Contact Flash Payments support for details on pricing.

    hashtag
    Retrieving some of your payments
    const bodyJSON = {
      variables: {
    
      query($input: PaymentQueryInput!) {
      payments
    
     {
      # there are more query parameters available, see the API schema
      "input": { 
        "statuses": "CLOSED",
        "toCurrencies": ["EUR","USD"]
      }
    }
    {
      "data": {
        "payments": [
          {
            "id": "5b04c62ec0bf606bf216ae21",
            "fromCurrency": "AUD",
            "toCurrency": "EUR"
          },
          {
            "id": "5b04c6bfc0bf606bf216af06",
            "fromCurrency": "AUD",
            "toCurrency": "USD"
          }
        ]
      }
    }

    hashtag
    Retrieving a single payment

    const bodyJSON = {
      variables: {
        input: "5b04c62ec0bf606bf216ae21",
      },
      query: `
    query ($input: ID) {  
      payment(id: $input) {
        status createdAt size
      }
    }`,
    };
    query($input: ID) {
      payment(id: $input) {
        status
        createdAt
        size
        # there are many other properties
      }
    }
    {
      # there are more query parameters available, see the API schema
      "input": "5b04c62ec0bf606bf216ae21"
    }
    {
      "data": {
        "payment": {
          "status": "CLOSED",
          "createdAt": "2018-08-13T05:45:28.698Z",
          "size": 1000
        }
      }
    }

    {
      "data": {
        "payments": [
          {
            "id": "5b04c62ec0bf606bf216ae21",
            "fromCurrency": "AUD",
            "toCurrency": "EUR"
          },
          {
            "id": "5b04c6bfc0bf606bf216af06",
            "fromCurrency": "AUD",
            "toCurrency": "USD"
          },
          {
            "id": "5b04c8e3c0bf606bf216b026",
            "fromCurrency": "EUR",
            "toCurrency": "AUD"
          }
        ]
      }
    }
    const bodyJSON = {
      variables: {
        input: {
        },
      },
      query: `
    query ($input: PaymentQueryInput!) {
      payments(input: $input) {   
        id fromCurrency toCurrency 
      }
    }`,
    };  
     query($input: PaymentQueryInput!) {
      payments(input: $input) {
        id
        fromCurrency
        toCurrency
        # there are many other properties
      }
    }
     {
      "input": { 
      }
    }

    Query withdrawals

    hashtag
    Retrieving all your withdrawals

    const bodyJSON = {
      variables: {
    
    query($input: WithdrawalQueryInput!) {
      withdrawals
    
    { 
      "input": {
      }
    }
    {
      "data": {
        "withdrawals": [
          {
            "id": "5b04c62ec0bf606bf216ae21",
            "recipient": {
              "firstName": "John"
              "lastName": "Smith"
            }
          },
          {
            "id": "5b04c6bfc0bf606bf216af06",
            "recipient": {
              "firstName": "John"
              "lastName": "Smith"
            }
          },
          {
            "id": "5b04c8e3c0bf606bf216b026",
            "recipient": {
              "firstName": "John"
              "lastName": "Smith"
            }
          }
        ]
      }
    }

    hashtag
    Retrieving some of your withdrawals

    hashtag
    Retrieving a single withdrawal

    Quote

    Quote the current bid and ask for a currency pair and size.

    hashtag
    Reference/indicative quotes

    Consider requesting an indicative/reference quote to understand the current currency trading rates before deciding to take action. Please be aware that market makers are not required to honor indicative quotes.

    Paste this query to the API Playground to request an indicative quote.

    const bodyJSON = {
      variables: {
    
    query($input: QuoteInput!) {
      quote(
    

    hashtag
    Multiple reference/indicative quotes with a single HTTP request

    If you send us too many API request - the system will automatically block you for a short period of time. To avoid that, we recommend sending multiple queries within a single HTTP request.

    Typically, you want to collect several dozen FX prices with a sincle API call. The GraphQL allows sending multiple queries within one HTTP request. Below is an example of such query:

    Here is a JavaScript code to build and send the above query string:

    Please be mindful. Do not fetch the rates you do not need. If there will be hundreds of quote queries within one HTTP request - it might timeout (take longer than 60 seconds).

    hashtag
    Tradable quote

    In contrast to an indicative quote, a tradable quote is guaranteed by the market maker.

    Paste this query to the GraphQL Playground to request a tradable quote. It is important to consider the expireAt date and time, and preserve the id of a tradable quote for future createPayment and createConversion calls.

    Rate limiting

    How to avoid and resolve HTTP 429 Too Many Requests

    hashtag
    Limits

    This API apply various rate limits depending on the type of HTTP request or GraphQL query being executed, as well as the number of such requests. The rate-limiting mechanism is quite dynamic and is based on the IP address(es), error rates, HTTP headers, and the GraphQL queries.

    We do not disclose the exact limits due to their complexity and our security policy. However, it's nearly impossible to reach the limits if your requests are properly formed.

    When one of the numerous limits exceeds the API typically responds with

    1. the HTTP status 429

    2. the HTTP header:

    3. and a JSON body:

    hashtag
    Common cases

    Here are the common situations when you might get yourself temporarily blocked:

    • When your requests produce numerous errors, e.g. malformed header, JSON body, or a GraphQL query.

    • When you send too many requests without a valid Authorization header.

    • When you send too many requests within a very short period.

    hashtag
    How to unblock if you see HTTP 429 responses

    Please contact our support team via the established communication channels. We will manually reset the counters for you.

    AMS statuses

    Adverse media search request statuses

    1. You submit a search. The request is created and queued. INITIALISED

    2. The background scan starts — web sources are fetched and analysed. INITIALISED → PENDING

    Testing CoP integration

    In the UAT environment, you can simulate different CoP responses by using specific substring keywords in the accountName field and any valid bsb and accountNo values.

    circle-info

    The pattern matching on the accountName field is substring-based and case-insensitive, e.g. using "Test Copimatch"

    input: {
    accountIdType: "BSB",
    bsb: "012003",
    accountNo: "123456789",
    accountName: "John Smith",
    },
    },
    query: `
    mutation ($input: CopInput!) {
    confirmationOfPayee(input: $input) {
    success code message billable
    }
    }`,
    };
    (
    input
    :
    $input
    )
    {
    success
    code
    message
    billable
    }
    }
    input: {
    statuses: "CLOSED",
    toCurrencies: ["EUR","USD"],
    },
    },
    query: `
    query ($input: PaymentQueryInput!) {
    payments(input: $input) {
    id fromCurrency toCurrency
    }
    }`,
    };
    (
    input
    :
    $input
    )
    {
    id
    fromCurrency
    toCurrency
    # there are many other properties
    }
    }
    input: {
    },
    },
    query: `
    query ($input: WithdrawalQueryInput!) {
    withdrawals(input: $input) {
    id
    recipient {
    firstName lastName
    }
    }
    }`,
    };
    (
    input
    :
    $input
    )
    {
    id
    recipient {
    firstName
    lastName
    }
    # there are many other properties
    }
    }
    const bodyJSON = {
      variables: {
        input: {
          statuses: "CONFIRMED",
          maxCreatedAt: "2020-01-29",
        },
      },
      query: `
    query ($input: WithdrawalQueryInput!) {
      withdrawals(input: $input) {   
        id createdAt 
      }
    }`,
    };  
    query($input: WithdrawalQueryInput!) {
      withdrawals(input: $input) {
        id
        createdAt 
        # there are many other properties
      }
    }
    input: {
    fromCurrency: "AUD",
    toCurrency: "USD",
    size: "10000",
    currency: "AUD",
    },
    },
    query: `
    query ($input: QuoteInput!) {
    quote(input: $input) {
    bid ask symbol timestamp inverted
    }
    }`,
    };
    input
    :
    $input
    )
    {
    bid
    ask
    symbol
    timestamp
    inverted
    }
    }

    Most often reason - when you collect reference prices/quotes using the quote query for multiple currency pairs. To avoid the issue you must send multiple GraphQL queries within a single HTTP request.

    {    
      # there are more query parameters available, see the API schema
      "input": {
        "statuses": "CONFIRMED",
        "maxCreatedAt": "2020-01-29"
      }  
    }
    {
      "data": {
        "withdrawals": [
          {
            "id": "5b04c62ec0bf606bf216ae21",
            "createdAt": "2020-01-17T07:21:20.247Z"
          },
          {
            "id": "5b04c6bfc0bf606bf216af06",
            "createdAt": "2018-08-13T05:45:28.698Z"
          }
        ]
      }
    }
    const bodyJSON = {
      variables: {
        input: "5b04c62ec0bf606bf216ae21",
      },
      query: `
    query ($input: ID) {  
      withdrawal(id: $input) {
        status createdAt amount
      }
    }`,
    };
    query($input: ID) {
      withdrawal(id: $input) {
        status
        createdAt
        amount
        # there are many other properties
      }
    }
    {
      # there are more query parameters available, see the API schema
      "input": "5b04c62ec0bf606bf216ae21"
    }
    {
      "data": {
        "withdrawal": {
          "status": "CONFIRMED",
          "createdAt": "2020-01-17T07:21:20.247Z",
          "amount": 1000
        }
      }
    }
    {
      "input": { 
        "fromCurrency": "AUD", 
        "toCurrency": "USD", 
        "size": "10000", 
        "currency": "AUD"
      }
    }
    {
      "data": {
        "quote": {
          "bid": 0.61104,
          "ask": 0.62077,
          "symbol": "USDAUD",
          "timestamp": "2018-08-13T07:54:54.993Z",
          "inverted": true
        }
      }
    }
    query {
      AUDUSD: quote(input: { fromCurrency: AUD, toCurrency: USD, size: 1000 }) { bid ask symbol }
      AUDEUR: quote(input: { fromCurrency: AUD, toCurrency: EUR, size: 1000 }) { bid ask symbol }
      AUDGBP: quote(input: { fromCurrency: AUD, toCurrency: GBP, size: 1000 }) { bid ask symbol }
    }
    {
      "data": {
        "AUDUSD": {
          "bid": 0.76508,
          "ask": 0.76922,
          "symbol": "AUDUSD"
        },
        "AUDEUR": {
          "bid": 0.64588,
          "ask": 0.64942,
          "symbol": "AUDEUR"
        },
        "AUDGBP": {
          "bid": 0.57091,
          "ask": 0.57404,
          "symbol": "AUDGBP"
        }
      }
    }
    const fromCurrencies = ["AUD"];
    const toCurrencies = ["USD", "EUR", "GBP"];
    const size = 1000;
    
    let query = "";
    for (const from of fromCurrencies) 
      for (const to of toCurrencies) 
        query += `${from}${to}: quote(input: { fromCurrency: ${from}, toCurrency: ${to}, size: ${size} }) { bid ask symbol }\n`;
    
    query = "query {\n" + query + "\n}";
    
    const response = await fetch("https://api.uat.flash-payments.com.au", { 
      method: "POST",
      headers: {
        authorization: "Bearer " + YOUR_TOKEN,
        "content-type": "application/json",
      },
      body: JSON.stringify({ query }),
    });
    const { data } = await response.json();
    const bodyJSON = {
      variables: {
        input: {
          fromCurrency: "AUD",
          toCurrency: "USD",
          size: "10000",
          currency: "AUD",
          tradable: true,
        },
      },
      query: `
    query ($input: QuoteInput!) { 
      quote(input: $input) {   
        bid ask symbol timestamp inverted expireAt id
      }
    }`,
    };
    query($input: QuoteInput!) {
      quote(input: $input) {
        bid
        ask
        symbol
        timestamp
        inverted
        expireAt
        id
      }
    }
     {
      "input": { 
        "fromCurrency": "AUD", 
        "toCurrency": "USD", 
        "size": "10000", 
        "currency": "AUD",
        "tradeable": true 
      }
    }
    {
      "data": {
        "quote": {
          "bid": 0.61339,
          "ask": 0.63101,
          "symbol": "AUDUSD",
          "timestamp": "2025-03-04T01:53:08.829Z",
          "inverted": false,
          "expireAt": "2025-03-04T01:55:08.830Z",
          "id": "67c65d04e5086d18751617ba"
        }
      }
    }
    Retry-After: 59
    {
      success: false,
      code: "TOO_MANY_REQUESTS",
      message: "Retry after 1 min",
      retrySecs: 59
    }
    PENDING →
    • COMPLETED — the scan finished successfully. Results are available in the results field. Final status.

    • FAILED — the scan could not be completed due to an error. The request is not billable. Final status.

    hashtag
    Most common status transitions

    Happy path

    INITIALISED → PENDING → COMPLETED

    Unhappy path

    INITIALISED → PENDING → FAILED

    circle-info

    A FAILED request is not billed. You may submit the same search again — a new request will be created and processed.

    hashtag
    Results

    Once a request reaches COMPLETED, the results field is populated with an array of AmsWebSearchResult objects. Each result represents a single web article found during the scan and includes:

    Field
    Description

    title

    Title of the web page

    snippet

    Web search snippet

    link

    URL of the article

    ,
    "John copimatch Smith"
    , or
    "COPIMATCH"
    will all trigger the same scenario.

    Here is a current list of the testing keywords and the most common response codesarrow-up-right. Please note this list can be changed over time.

    Account Name Keyword
    Response Code
    Simulated Account Type

    copimatch

    MATCH

    Individual

    copijmatch

    MATCH

    Individual (joint account)

    circle-info

    You can start with testing CoP requests in the API Playgroundarrow-up-right. Log in with your UAT credentials and use the confirmationOfPayee mutation.

    hashtag
    Integration Examples

    hashtag
    CoP as a standalone investigation tool

    CoP can be used independently from your payment flows as an account investigation tool. For example, you may want to verify account holder details during onboarding, reconciliation, or dispute resolution, without initiating a payment. A typical investigation flow looks like this:

    1. Collect the account details you wish to verify: BSB, account number, and the expected account holder name.

    2. Call confirmationOfPayee with those details.

    3. Inspect the code in the response.

    4. If MATCH then the account holder name is confirmed. Record the result for your records.

    5. If CLOSE_MATCH then the name partially matches. Review the message for details and decide whether further investigation is needed.

    6. If NOT_MATCH then the name does not match the account. This may warrant further due diligence.

    7. If ACCOUNT_CLOSED or ACCOUNT_NOT_FOUND then the account is no longer active or does not exist. Flag accordingly.

    8. If COP_PLATFORM_ERROR then the check could not be completed. The account may have opted out of CoP. Retry later or use alternative verification methods.

    circle-info

    Each CoP request is logged and available in your FlashConnectarrow-up-right request history, making it easy to maintain an audit trail of your verification checks.

    hashtag
    CoP as a part of your payment integration flow

    circle-exclamation

    While CoP is fully functional on our platform, and the adoption among Australian financial institutions is growing, the Australian CoP coverage is currently limited.

    This means a significant portion of accounts may return ACCOUNT_NOT_FOUND or COP_PLATFORM_ERROR not because the details are wrong, but because the receiving institution does not yet fully participate in CoP.

    Additionally, financial institutions store account holder names in varying formats (e.g., abbreviated names, reordered words, special characters). The current matching algorithm used by the Australian Payments Plus (AP+) relies on basic string similarity, which can produce false-negative NOT_MATCH results for accounts that are, in fact, correct.

    For this reason, we currently recommend using CoP as a standalone verification tool rather than as a blocking step in your payment flow.

    A typical future integration flow could look like this:

    1. Before submitting a payment or withdrawal, call confirmationOfPayee with the recipient's account details.

    2. Inspect the code in the response.

    3. If MATCH then proceed with the payment.

    4. If CLOSE_MATCH then display a warning to your user and let them decide whether to proceed.

    5. If NOT_MATCH then alert the user and recommend they verify the account details.

    6. If ACCOUNT_CLOSED or ACCOUNT_NOT_FOUND then block the payment and ask the user to provide correct details.

    7. If COP_PLATFORM_ERROR then optionally proceed, as the account may have opted out of CoP.

    circle-info

    CoP is advisory. The response does not block payments automatically. It is your responsibility to act on the result codes appropriately for your use case.

    hashtag
    Error Handling

    If your account does not have CoP enabled, the API will return:

    Standard rate limitingarrow-up-right applies to CoP requests. Additionally, CoP has its own usage limits. If you exceed them, you will receive the COP_LIMIT_EXCEEDED code.

    circle-info

    When the response codearrow-up-right is COP_PLATFORM_ERROR, it may indicate that the account holder has opted out of CoP verification. The general recommendation is to proceed with the payment.

    {
      "data": {
        "confirmationOfPayee": {
          "success": false,
          "code": "COP_API_DISABLED",
          "message": "Confirmation Of Payee API is disabled. Please contact support.",
          "billable": false
        }
      }
    }

    Run AMS Request

    hashtag
    Adverse Media Search

    To run a search, execute the adverseMediaSearch mutation as below.

    hashtag

    adversityScore

    Overall adversity score, 0–100. Higher = more adverse content found

    personSimilarity

    Similarity between the search subject and the person in the article, 0–100

    role

    Role of the subject in the article — e.g. perpetrator, victim, other

    roleDetails

    Further detail on the role or alleged involvement

    summary

    One-sentence summary of the article

    extractedCountry

    ISO country code extracted from the article, if detected

    extractedState

    State or region extracted from the article, if detected

    locationMismatch

    true if the article's detected location does not match the supplied country

    paywall

    true if the article is behind a paywall and could not be fully analysed

    exactFullNameMatch

    true if the article contains an exact match of the full name

    dob

    Date of birth extracted from the article, if detected

    ageInArticle

    Age of the person extracted from the article, if detected

    articlePublishDate

    Publication date of the article, if detected

    lookup

    Keywords found in the article and their occurrence counts

    copcmatch

    MATCH

    Company

    copiclosematch

    CLOSE_MATCH

    Individual

    copijclosematch

    CLOSE_MATCH

    Individual (joint account)

    copcclosematch

    CLOSE_MATCH

    Company

    copinotmatch

    NOT_MATCH

    Individual

    copcnotmatch

    NOT_MATCH

    Company

    copclosed

    ACCOUNT_CLOSED

    -

    copnotfound

    ACCOUNT_NOT_FOUND

    -

    coperror

    COP_PLATFORM_ERROR

    -

    Search for an individual
    const bodyJSON = {
      variables: {
    
    mutation($input: AmsRequestInput!) {
      adverseMediaSearch(input: $input) {
        success
        code
        message
        amsRequest {
          id
          status
        }
      }
    }
    {
      "input": {
        "firstName": "John",
        "lastName": "Smith",
        "country": "AU"
      }
    }
    {
      "data": {
        "adverseMediaSearch": {
          "success": true,
          "code": "SCAN_SCHEDULED",
          "message": "Name scan scheduled",
          "amsRequest": {
            "id": "6820a4f3e1c2b5d8f0123456",
            "status": "INITIALISED"
          }
        }
      }
    }

    hashtag
    Search for an organisation

    Use accountName instead of individual name fields when screening a business or other non-person entity.

    const bodyJSON = {
      variables: {
        input: {
          accountName: "Acme Pty Ltd",
          country: "AU",
        },
      },
      query: `
    mutation ($input: AmsRequestInput!) {
      adverseMediaSearch(input: $input) {
        success
        code
        message
        amsRequest {
          id
          status
        }
      }
    }`,
    };
    mutation($input: AmsRequestInput!) {
      adverseMediaSearch(input: $input) {
        success
        code
        message
        amsRequest {
          id
          status
        }
      }
    }
    {
      "input": {
        "accountName": "Acme Pty Ltd",
        "country": "AU"
      }
    }
    {
      "data": {
        "adverseMediaSearch": {
          "success": true,
          "code": "SCAN_SCHEDULED",
          "message": "Name scan scheduled",
          "amsRequest": {
            "id": "6820b1d9c3f4a7e2d0987654",
            "status": "INITIALISED"
          }
        }
      }
    }

    hashtag
    Name — firstName / lastName / middleName or accountName

    For individuals, provide firstName and lastName. The optional middleName improves matching accuracy.

    For organisations, use accountName instead. You cannot combine accountName with individual name fields.

    circle-exclamation

    Either accountName or at least one of firstName / lastName is required. Providing both will result in a validation error.

    hashtag
    Country — country

    A two-letter ISO 3166-1 alpha-2 country code (e.g. AU, US, GB). This is required and used to contextualise results — articles where the detected location does not match the supplied country are flagged via locationMismatch.

    hashtag
    Background scan — tracking progress

    The scan runs in the background and may take several minutes. The mutation returns immediately with status: INITIALISED. Use the returned id to poll for results or subscribe to webhook events to be notified when the scan progresses.

    Webhook events fired during a scan:

    Event
    Status

    ams_initialised

    INITIALISED

    ams_pending

    PENDING

    ams_completed

    COMPLETED

    ams_failed

    See AMS statuses for the full lifecycle.

    hashtag
    Deduplication

    If you submit a search for the same name and country more than once within the same calendar day, the existing request is returned rather than creating a new one. The code field indicates whether the scan was newly scheduled or is already in progress or complete:

    Code
    Meaning

    SCAN_SCHEDULED

    New scan created and queued

    SCAN_ALREADY_SCHEDULED

    A scan for this name and country is already in progress today

    SCAN_ALREADY_COMPLETED

    A completed scan for this name and country already exists today

    hashtag
    Monthly request limit

    A free monthly limit applies to AMS requests. Once reached, success: false is returned with code: LIMIT_EXCEEDED. Contact support to increase your limit.

    Auto receive funds

    Automatically receive and convert funds from other countries and currencies

    Some customers can automatically receive funds from overseas. Meaning, if we detect an overseas deposit to the Flash Payments controlled bank account(s) then we can automatically create an inbound payment, convert funds, and top up your Flash Payments balance with AUD.

    circle-exclamation

    Please note that funds must be transferred from a bank account registered under your company name. If a virtual Flash sub-account is used as the beneficiary, the transfer should be made from an account in your sub-client’s name. Whenever a sub-client record is involved in the transaction, their full real-world address is always required. For your local Australian sub-clients, please ensure all address components are provided when adding a sub-client to our system. In some cases, but not always, the payment must include the specific payment reference we provide. See below for more details.

    Here is how it looks step by step.

    Query AMS requests

    hashtag
    Retrieving a single AMS request

    Use the amsRequest query with the id returned from the adverseMediaSearch mutation to check the status of a scan or retrieve its results.

    Bank information

    Ensuring bank details are correct

    To validate BSB, BIC (aka SWIFT code) or IBAN use the bankInfo query.

    circle-info

    The bankInfo query accepts only one of bsb, bic, or iban arguments. Otherwise, it will return an error.

    input: {
    firstName: "John",
    lastName: "Smith",
    country: "AU",
    },
    },
    query: `
    mutation ($input: AmsRequestInput!) {
    adverseMediaSearch(input: $input) {
    success
    code
    message
    amsRequest {
    id
    status
    }
    }
    }`,
    };

    FAILED

  • We would need to enable the foreign currency auto-receiving feature for you.

  • You, or your Sub-client, would have a special bank account in, say, SEPA zone. Find the details below.

    • The account number and payment reference depends on the currency and country you wish to deposit to. E.g. the EUR currency account is usually a British IBAN (starts with "GB").

  • You, or your , would deposit money to it. Make sure to submit the exact payment reference we told you! Otherwise, your funds will be returned.

  • The Flash Payments would detect the account funding event and automatically create a EUR->AUD payment for you.

  • You would receive at least two webhook notifications - payment_created and payment_complete.

  • Your Flash Payments AUD balance would increase accordingly.

  • hashtag
    Funding Accounts

    To find which foreign currency bank account you need to deposit into, please visit FlashConnectarrow-up-right and locate the list of supported inbound currencies and their corresponding bank account numbers. It is referred to as the “Funding Accounts” throughout the user interface.

    circle-info

    You can simulate and test an international inbound payment with the FlashConnect tool in the UAT environment. Just go to the FX Payments page and click "SEND TEST INBOUND PAYMENT". Additionally, you can test an international inbound payment sent by your sub-client in the UAT. Just go to the Sub-clients page, find the sub-client, and click "SEND TEST INBOUND PAYMENT".

    To find out the Funding Accounts via API please use the fundingAccounts query.

    You should deposit your foreign currency to one of the following master accounts:

    const bodyJSON = {
      variables: {
    
      query($input: FundingAccountQueryInput!) {
      fundingAccounts
    
     {
      "input": { 
        "currencies": ["EUR", "USD", "HKD", "CNY"] 
      }
    }
    {
      "data": {
        "fundingAccounts": [
          {
            "iban": "GB91 BARC 2006 0565 4685 66",
            "accountNo": "65468566",
            "bic": "BARCGB22",
            "currency": "USD",
            "externalReference": "191127-99999"
          },
          {
            "iban": "GB05 BARC 2006 0574 7412 77",
            "accountNo": "74741277",
            "bic": "BARCGB22",
            "currency": "EUR",
            "externalReference": "191127-99999"
          },
          {
            "iban": null,
            "accountNo": "87135588",
            "bic": "BARCGB22",
            "currency": "CNY",
            "externalReference": "191127-99999"
          },
          {
            "iban": "GB87 BARC 2006 0546 9946 00",
            "accountNo": "46994600",
            "bic": "BARCGB22",
            "currency": "HKD",
            "externalReference": "191127-99999"
          }
        ]
      }
    }

    Your sub-clients should deposit their foreign currency to one of the follwing virtual sub-accounts:

    const bodyJSON = {
      variables: {
        sc: {
          externalId: "991188227733",
        },
        fa: {
          currencies: ["EUR","USD","CNY"],
        },
      },
      query: `
    query ($sc: SubClientQueryInput!, $fa: FundingAccountQueryInput!) {
      subClients(input: $sc) {
        id externalId 
        fundingAccounts(input: $fa) {
          iban accountNo accountName accountAddress bic currency externalReference
        }
      }
    }`,
    };
    query($sc: SubClientQueryInput!, $fa: FundingAccountQueryInput!) {
      subClients(input: $sc) {
        id
        externalId
        fundingAccounts(input: $fa) {
          iban
          accountNo
          accountName
          accountAddress
          bic
          currency
          externalReference
        }
      }
    }
     {
      "sc": { 
        "externalId": "991188227733" 
      },
      "fa": {
        "currencies": ["EUR", "USD", "CNY"] 
      }
    }
    {
      "data": {
        "subClients": [
          {
            "id": "60a1e9e76eaedbf66964a323",
            "externalId": "991188227733",
            "fundingAccounts": [
              {
                "iban": "GB91 BARC 2006 0565 4685 66",
                "accountNo": "65468566",
                "bic": "BARCGB22",
                "currency": "USD",
                "externalReference": "210616-99999"
              },
              {
                "iban": "GB05 BARC 2006 0574 7412 77",
                "accountNo": "74741277",
                "bic": "BARCGB22",
                "currency": "EUR",
                "externalReference": "210616-99999"
              },
              {
                "iban": null,
                "accountNo": "87135588",
                "bic": "BARCGB22",
                "currency": "CNY",
                "externalReference": "210616-99999"
              },
            ]
          }
        ]
      }
    }
    {
      "id": "6820a4f3e1c2b5d8f0123456"
    }
    {
      "data": {
        "amsRequest": {
          "id": "6820a4f3e1c2b5d8f0123456",
          "name": "John Smith",
          "country": "AU",
          "status": "COMPLETED",
          "createdAt": "2025-03-15T08:23:14.521Z",
          "results": [
            {
              "title": "Local businessman John Smith fined for tax evasion",
              "link": "https://example-news.com.au/articles/smith-tax",
              "adversityScore": 72,
              "personSimilarity": 85,
              "summary": "John Smith of Sydney was fined $45,000 for understating income over three financial years."
            }
          ]
        }
      }
    }
    circle-info

    The results field is populated only once the scan reaches COMPLETED status. While the scan is INITIALISED or PENDING, results will be null.

    hashtag
    Retrieving all your AMS requests

    const bodyJSON = {
      variables: {
        input: {},
      },
      query: `
    query ($input: AmsQueryInput) {
      amsRequests(input: $input) {
        id
        name
        country
        status
        createdAt
      }
    }`,
    };
    query($input: AmsQueryInput) {
      amsRequests(input: $input) {
        id
        name
        country
        status
        createdAt
        # there are many other properties
      }
    }
    {
      "input": {}
    }
    {
      "data": {
        "amsRequests": [
          {
            "id": "6820a4f3e1c2b5d8f0123456",
            "name": "John Smith",
            "country": "AU",
            "status": "COMPLETED",
            "createdAt": "2025-03-15T08:23:14.521Z"
          },
          {
            "id": "6820b1d9c3f4a7e2d0987654",
            "name": "Acme Pty Ltd",
            "country": "AU",
            "status": "PENDING",
            "createdAt": "2025-03-15T09:01:44.008Z"
          }
        ]
      }
    }

    hashtag
    Filtering AMS requests

    Use the input parameter to narrow results by status, date range, or name.

    const bodyJSON = {
      variables: {
        input: {
          statuses: ["COMPLETED"],
          minCreatedAt: "2025-03-01T00:00:00.000Z",
          maxCreatedAt: "2025-04-01T00:00:00.000Z",
          country: "AU",
        },
      },
      query: `
    query ($input: AmsQueryInput) {
      amsRequests(input: $input) {
        id
        name
        country
        status
        createdAt
      }
    }`,
    };
    query($input: AmsQueryInput) {
      amsRequests(input: $input) {
        id
        name
        country
        status
        createdAt
      }
    }
    {
      # there are more filter parameters available, see the API schema
      "input": {
        "statuses": ["COMPLETED"],
        "minCreatedAt": "2025-03-01T00:00:00.000Z",
        "maxCreatedAt": "2025-04-01T00:00:00.000Z",
        "country": "AU"
      }
    }
    {
      "data": {
        "amsRequests": [
          {
            "id": "6820a4f3e1c2b5d8f0123456",
            "name": "John Smith",
            "country": "AU",
            "status": "COMPLETED",
            "createdAt": "2025-03-15T08:23:14.521Z"
          }
        ]
      }
    }

    Available filter fields on AmsQueryInput:

    Field
    Description

    statuses

    Filter by one or more AMS statuses

    minCreatedAt

    Return only requests created after this timestamp (ISO 8601)

    maxCreatedAt

    Return only requests created before this timestamp (ISO 8601)

    query($id: ID!) {
      amsRequest(id: $id) {
        id
        name
        country
        status
        createdAt
        results {
          title
          link
          adversityScore
          personSimilarity
          summary
          # there are many other result fields
        }
      }
    }
    const bodyJSON = {
      variables: {
        id: "6820a4f3e1c2b5d8f0123456",
      },
      query: `
    query ($id: ID!) {
      amsRequest(id: $id) {
        id
        name
        country
        status
        createdAt
        results {
          title
          link
          adversityScore
          personSimilarity
          summary
        }
      }
    }`,
    };
    The below sample queries will return null if the BSB, BIC, IBAN is not found.

    Validate BSB

    const bodyJSON = {
      variables: {
    
    query($input: BankInfoQueryInput!){
      bankInfo
    
     {
      "input": {
        "bsb": "012622"
      }
    }
    {
      "data": {
        "bankInfo": {
          "name": "ANZ",
          "address": {
            "building": null,
            "street": "Shop 1  Westfield Shopping Ctr",
            "suburb": "Figtree",
            "state": "NSW",
            "country": "AU",
            "postcode": "2525"
          }
        }
      }
    }

    Validate BIC

    const bodyJSON = {
      variables: {
        input: {
          bic: "BARCGB22",
        },
      }, 
      query: `
    query ($input: BankInfoQueryInput!) {
      bankInfo(input: $input) {
        name 
        address {
          building street suburb state country postcode
        }
      }
    }`,
    };
    query($input: BankInfoQueryInput!){
      bankInfo(input: $input) {
        name
        address {
          building
          street
          suburb
          state
          country
          postcode
        }
      }
    }
     {
      "input": {
        "bic": "BARCGB22"
      }
    }
    {
      "data": {
        "bankInfo": {
          "name": "BARCLAYS BANK PLC",
          "address": {
            "building": null,
            "street": "1 CHURCHILL PLACE, CANARY WHARF London",
            "suburb": "London",
            "state": null,
            "country": "GB",
            "postcode": "E14 5HP"
          }
        }
      }
    }

    Validate IBAN

    const bodyJSON = {
      variables: {
        input: {
          iban: "DE59500105178646768962",
        },
      }, 
      query: `
    query ($input: BankInfoQueryInput!) {
      bankInfo(input: $input) {
        name 
        address {
          building street suburb state country postcode
        }
      }
    }`,
    };
    query($input: BankInfoQueryInput!){
      bankInfo(input: $input) {
        name
        address {
          building
          street
          suburb
          state
          country
          postcode
        }
      }
    }
     {
      "input": {
        "iban": "DE59500105178646768962"
      }
    }
    {
      "data": {
        "bankInfo": {
          "name": "ING-DIBA AG (RETAIL BANKING)",
          "address": {
            "building": null,
            "street": "THEODOR-HEUSS-ALLEE 2 Frankfurt Am Main",
            "suburb": "Frankfurt Am Main",
            "state": null,
            "country": "DE",
            "postcode": "60486"
          }
        }
      }
    }

    Send funds

    How to send orchestrated account-to-account payments which include FX

    To make a payment from AUD to a different currency, you need to execute the createPayment mutation as below.

    circle-info

    Note that you must have enough AUD balance to make an outbound AUD payment.

    const bodyJSON = {
      variables: {
    
     mutation($input: PaymentInput!) {
      createPayment(input: $input) {
        success
        code
        message
        payment {
          id
          status
          size
        }
      }
    }
    {
      "input": { 
        "fromCurrency": "AUD",
        "toCurrency": "GBP",
        "size": 1000,
        "currency": "AUD",
        "reason": "BUSINESS",
        "sourceOfFunds": "BUSINESS_FUNDS",
        "externalReference": "my ref 221b",
        "externalId": "12344321",
        "idempotencyKey": "12344321"
      }
    }

    hashtag
    Recipient - recipient object or recipientId

    You can either and provide us with the recipientId or submit a valid recipient object directly to createPayment as shown in the above example. We recommend the latter where possible, as you won’t need to send an extra HTTP request. Please note that a new recipient record won’t be created in this case.

    circle-exclamation

    We are legally obliged to collect the actual sender and beneficiary details. Please do not send us intermediate organisation details such as exchanges, banks, gateways, etc.

    If it is an intermediate, please see instead.

    Please always send us the ultimate sender and recipient. If sending funds to yourself, please provide your own details. See the schema in for other recipient details options.

    hashtag
    Sender - sender object, senderId, subClientId , or neither

    Just like submitting recipient information, you can either and provide us with the senderId or directly submit a valid sender object to createPayment as shown in the above example. Please note that a new sender record won’t be created in the latter case. Alternatively, if your account is configured to send funds on behalf of your , you may provide us with the subClientId and the FX payment created will be linked to that sub-client. In this case the sub-client will be used as the sender and reported to the government.

    To use subClientId as the sender for your withdrawal, please execute the createPayment mutation as below.

    If your company is the ultimate sender for an FX payment, you can skip both the senderId and subClientId. In this situation, we will use your company’s Flash account as the sender for the payment. Please note that a new sender record will not be created in this case.

    Please execute the following createPayment mutation to use your company's Flash account details as sender.

    hashtag
    Callback (aka ) URI

    We recommend against continuous polling for payment status changes. Instead, please use callbackUri.

    The optional callbackUri will be invoked several times during the processing of a payment. These callbacks will usually occur soon (within several seconds) after the initial create payment call - but may be delayed in some cases. The example JSON payloads can be found on the .

    Please note that toAmount (or fromAmount) and other fluctuating payment properties can change during payment execution.

    triangle-exclamation

    Security note

    The callback (aka ) endpoint URI can be invoked by anyone in the internet. Thus opening up a potential attack vector. See page to secure your data properly.

    Withdraw funds

    Send money from your Flash Payments balances to Australian bank accounts or internationally per your approved use case.

    To make a withdrawal, you need to execute the createWithdrawal mutation as below.

    circle-info

    You must have enough in your account for the chosen currency to make a withdrawal.

    input: {
    bsb: "012622",
    },
    },
    query: `
    query ($input: BankInfoQueryInput!) {
    bankInfo(input: $input) {
    name
    address {
    building street suburb state country postcode
    }
    }
    }`,
    };
    (
    input
    :
    $input
    )
    {
    name
    address {
    building
    street
    suburb
    state
    country
    postcode
    }
    }
    }

    firstName

    Filter by first name — case insensitive, partial match

    middleName

    Filter by middle name — case insensitive, partial match

    lastName

    Filter by last name — case insensitive, partial match

    accountName

    Filter by business name — case insensitive, partial match

    country

    Filter by two-letter ISO country code

    input: {
    currencies: ["EUR","USD","HKD","CNY"],
    },
    },
    query: `
    query ($input: FundingAccountQueryInput!) {
    fundingAccounts(input: $input) {
    iban accountNo accountName accountAddress bic currency externalReference
    }
    }`,
    };
    (
    input
    :
    $input
    )
    {
    iban
    accountNo
    accountName
    accountAddress
    bic
    currency
    externalReference
    }
    }
    Sub-client
    If sending funds from yourself, there's an option to use your company's Flash account details as sender by default. Please consider the examples below.
    input: {
    fromCurrency: "AUD",
    toCurrency: "GBP",
    size: 1000,
    currency: "AUD",
    reason: "BUSINESS",
    sourceOfFunds: "BUSINESS_FUNDS",
    externalReference: "my ref 221b",
    sender: {
    companyName: "Acme AU Ltd",
    address: {
    street: "1 Hay St SYDNEY NSW 2000",
    country: "AU",
    },
    },
    recipient: {
    iban: "GB33BARC20001234567890",
    companyName: "Acme GB Ltd",
    currency: "GBP",
    accountIdType: "IBAN",
    address: {
    street: "1 Main St LONDON SW1A 1AA",
    country: "GB",
    },
    },
    externalId: "12344321",
    idempotencyKey: "12344321",
    },
    },
    query: `
    mutation ($input: PaymentInput!) {
    createPayment(input: $input) {
    success code message
    payment {
    id status size
    }
    }
    }`,
    };
    pre-create recipientsarrow-up-right
    Instiutions
    Playgroundarrow-up-right
    pre-create a sender
    sub-clientsarrow-up-right
    Webhook
    Webhooks page
    webhook
    Webhooks

    hashtag
    Payment reference - externalReference

    Arbitrary text, which will be seen in the ultimate recipient's bank statement. E.g. "invoice #123". Will be eventually truncated to 18 ASCII chars if delivered via Australia's old (DE, Direct Entry) payment system. However, if you choose to use the real-time NPP network, then the maximum length is 280 chars.

    hashtag
    Recipient - recipient object or recipientId

    You can either pre-create recipients and provide us with the recipientId or submit a valid recipient object directly to createWithdrawal as shown in the above example. We recommend the latter where possible, as you won’t need to send an extra HTTP request. Please note that a new recipient record won’t be created in this case.

    circle-info

    Please also note that the recipient's Australian accountIdType must be either BSB or PAYID (coming soon).

    hashtag
    Sender - sender object, senderId, subClientId , or neither

    Just like submitting recipient information, you can either pre-create a sender and provide us with the senderId or directly submit a valid sender object to createWithdrawal as shown in the above example. Please note that a new sender record won’t be created in the latter case. Alternatively, if your account is configured to disburse funds on behalf of your sub-clientsarrow-up-right, you may provide us with the subClientId and the withdrawal created will be linked to that sub-client. In this case the sub-client will be used as the sender and reported to the government.

    To use subClientId as the sender for your withdrawal, please execute the createWithdrawal mutation as below.

    circle-exclamation

    We are legally obliged to collect the actual sender and beneficiary details. Please do not send us intermediate organisation details such as exchanges, banks, gateways, etc.

    If it is an intermediate, please see Instiutions instead.

    Please always send us the ultimate sender and recipient. If sending funds to yourself, please provide your own details. See the schema in Playgroundarrow-up-right for other recipient details options.

    If sending funds from yourself, there's an option to use your company's Flash account details as sender by default. Please consider the example below.

    If your company is the ultimate sender for a withdrawal, you can skip both the senderId (or sender object) and subClientId. In this situation, we will use your company’s Flash account as the sender for the transaction. Please note that a new sender record will not be created in this case.

    Please execute the following createWithdrawal mutation to use your company's Flash account details as sender.

    hashtag
    Instructing Institutions

    An organisation that instructed you to make a withdrawal. This data is mandatory if you submit this withdrawal on behalf of another financial institution.

    circle-info

    For more information please see Institutions.

    hashtag
    Using existing institutions instructingInstitutionId

    This optional field refers to an existing Institution that was created earlier in the Flash Connect interface or via this API.

    hashtag
    Create institutions on the fly using the instructingInstitution field

    Optional field that allows you to provide Institution details without pre-creating one. Once passed, Flash Payments will create the Institution for you. Before creating an institution, we will try to find an existing one:

    • By instructingInstitution.externalId if present.

    • By instructingInstitution.businessNumber AND instructingInstitution.address.country

    hashtag
    Callback (aka Webhook) URI

    We recommend against continuous polling for withdrawal status changes. Instead, please use callbackUri.

    The optional callbackUri will be invoked several times during the processing of a withdrawal. These callbacks will usually occur soon (within several seconds) after the initial create withdrawal call - but may be delayed in some cases. The example JSON payloads can be found on the Webhooks page.

    triangle-exclamation

    Security note

    The callback (aka webhook) endpoint URI can be invoked by anyone on the internet. Thus opening up a potential attack vector. See Webhooks page to secure your data properly.

    balance
    const bodyJSON = {
      variables: {
        input: {
          amount: 1000,
          currency: "AUD",
          sender: {
            companyName: "Acme LLC",
            address: {
              street: "1 Jon St PORTLAND VA 54321",
              country: "US",
            },
          },
          recipient: {
            bsb: "370370",
            accountNo: "123123123",
            companyName: "Acme Pty Ltd",
            currency: "AUD",
            accountIdType: "BSB",
            address: {
              street: "1 Main St SYDNEY NSW 2000",
              country: "AU",
            },
          },
          externalReference: "invoice #1234",
          externalId: "12344321",
          idempotencyKey: "12344321",
        },
      },
      query: `
    
mutation ($input: CreateWithdrawalInput!) { 
      createWithdrawal(input: $input) { 
        success code message withdrawal { 
          id status amount currency 
        } 
      } 
    }`,
    };  
    {
      "data": {
        "createPayment": {
          "success": true,
          "code": "SUCCESS",
          "message": "Scheduled for immediate execution",
          "payment": {
            "id": "60711af8c078ba061f623531",
            "status": "OPEN",
            "size": 1000
          }
        }
      }
    }
    const bodyJSON = {
      variables: {
        input: {
          fromCurrency: "AUD",
          toCurrency: "GBP",
          size: 1000,
          currency: "AUD",
          reason: "BUSINESS",
          sourceOfFunds: "BUSINESS_FUNDS",
          externalReference: "my ref 221b",
          subClientId: "6092360bf40f2dgc52f85cf1",
          recipient: {
            iban: "GB33BARC20001234567890",
            companyName: "Acme GB Ltd",
            currency: "GBP",
            accountIdType: "IBAN",
            address: {
              street: "1 Main St LONDON SW1A 1AA",
              country: "GB",
            },
          },
          externalId: "123443212",
          idempotencyKey: "123443212",
        },
      },
      query: ` 
    mutation ($input: PaymentInput!) {
      createPayment(input: $input) {
        success code message
        payment {
          id status size
        }
      }
    }`,
    };
     mutation($input: PaymentInput!) {
      createPayment(input: $input) {
        success
        code
        message
        payment {
          id
          status
          size
        }
      }
    }
    {
      "input": { 
        "fromCurrency": "AUD",
        "toCurrency": "GBP",
        "size": 1000,
        "currency": "AUD",
        "reason": "BUSINESS",
        "sourceOfFunds": "BUSINESS_FUNDS",
        "externalReference": "my ref 221b",
        "subClientId": "6092360bf40f2dgc52f85cf1",
        "externalId": "12344321",
        "idempotencyKey": "12344321"
      }
    }
    {
      "data": {
        "createPayment": {
          "success": true,
          "code": "SUCCESS",
          "message": "Scheduled for immediate execution",
          "payment": {
            "id": "60711bg8d078cb061g623531",
            "status": "OPEN",
            "size": 1000
          }
        }
      }
    }
    const bodyJSON = {
      variables: {
        input: {
          fromCurrency: "AUD",
          toCurrency: "GBP",
          size: 1000,
          currency: "AUD",
          reason: "BUSINESS",
          sourceOfFunds: "BUSINESS_FUNDS",
          externalReference: "my ref 2234",
          recipient: {
            iban: "GB33BARC20001234567890",
            companyName: "Acme GB Ltd",
            currency: "GBP",
            accountIdType: "IBAN",
            address: {
              street: "1 Main St LONDON SW1A 1AA",
              country: "GB",
            },
          },
          externalId: "0123443210",
          idempotencyKey: "0000012344321000",
        },
      },
      query: ` 
    mutation ($input: PaymentInput!) {
      createPayment(input: $input) {
        success code message
        payment {
          id status size
          sender {
            firstName lastName companyName
          }
        }
      }
    }`,
    };
     mutation($input: PaymentInput!) {
      createPayment(input: $input) {
        success
        code
        message
        payment {
          id
          status
          size   
          sender {
            firstName 
            lastName 
            companyName
          }
        }
      }
    }
    {
      "input": { 
        "fromCurrency": "AUD",
        "toCurrency": "GBP",
        "size": 1000,
        "currency": "AUD",
        "reason": "BUSINESS",
        "sourceOfFunds": "BUSINESS_FUNDS",
        "externalReference": "my ref 2234",
        "externalId": "0123443210",
        "idempotencyKey": "0000012344321000"
      }
    }
    {
      "data": {
        "createPayment": {
          "success": true,
          "code": "SUCCESS",
          "message": "Scheduled for immediate execution",
          "payment": {
            "id": "67d8e98caaa23286e1a1fd00",
            "status": "OPEN",
            "size": 1000,
            "sender": {
              "firstName": "John",
              "lastName": "Smith",
              "companyName": "Smith Consulting Pty Ltd"
            }
          }
        }
      }
    }
    {
      "input": {
        "amount": 1000,
        "currency": "AUD",
        "sender": {
          "companyName": "Acme LLC",
          "address": {
            "street": "1 Jon St PORTLAND VA 54321",
            "country": "US"
          }
        },
        "recipient": {
          "bsb": "370370",
          "accountNo": "123123123",
          "companyName": "Acme Pty Ltd",
          "currency": "AUD",
          "accountIdType": "BSB",
          "address": {
            "street": "1 Main St SYDNEY NSW 2000",
            "country": "AU"
          }
        },
        "externalReference": "invoice #1234",
        "externalId": "12344321",
        "idempotencyKey": "12344321"
      }
    }
    {
      "data": {
        "createWithdrawal": {
          "success": true,
          "code": "SUCCESS",
          "message": "Withdrawal was created",
          "withdrawal": {
            "id": "6904332f42b934e1954a734e",
            "status": "INITIALISED",
            "amount": 1000,
            "currency": "AUD"
          }
        }
      }
    }
    const bodyJSON = {
      variables: {
        input: {
          amount: 1000, 
          currency: "AUD",
          externalReference: "invoice #1234",
          recipient: {
            bsb: "370370",
            accountNo: "123123123",
            companyName: "Acme Pty Ltd",
            currency: "AUD",
            accountIdType: "BSB",
            address: {
              street: "1 Main St SYDNEY NSW 2000",
              country: "AU",
            },
          },
          subClientId: "3fbj71b1dc328d56g94g9375",
          externalId: "123443212",
          idempotencyKey: "123443212",
        },
      }, 
      query: ` 
    mutation ($input: CreateWithdrawalInput!) {
      createWithdrawal(input: $input) {
        success code message    
        withdrawal {
          id status amount currency    
        }  
      }
    }`,
    };
     mutation($input: CreateWithdrawalInput!) {
      createWithdrawal(input: $input) {
        success
        code
        message
        withdrawal {
          id
          status
          amount
          currency
        }
      }
    }
     { 
        "input": {
          "amount": 1000,
          "currency": "AUD",
          "externalReference": "invoice #1234",
          "recipient": {
            "bsb": "370370",
            "accountNo": "123123123",
            "companyName": "Acme Pty Ltd",
            "currency": "AUD",
            "accountIdType": "BSB",
              "address": {
                "street": "1 Main St SYDNEY NSW 2000",
                "country": "AU"
              }
           },
          "subClientId": "3fbj71b1dc328d56g94g9375",
          "externalId": "123443212",
          "idempotencyKey": "123443212"
        }
    }
    {
      "data": {
        "createWithdrawal": {
          "success": true,
          "code": "SUCCESS",
          "message": "Withdrawal was created",
          "withdrawal": {
            "id": "60711af8c078ba061f623531",
            "status": "INITIALISED",
            "amount": 1000,
            "currency": "AUD"
          }
        }
      }
    }
    const bodyJSON = {
      variables: {
        input: {
          amount: 500, 
          currency: "AUD",
          externalReference: "invoice #123",
          recipient: {
            bsb: "370370",
            accountNo: "123123123",
            companyName: "Acme Pty Ltd",
            currency: "AUD",
            accountIdType: "BSB",
            address: {
              street: "1 Main St SYDNEY NSW 2000",
              country: "AU",
            },
          },
          externalId: "1234567890",
          idempotencyKey: "0987654321",
        },
      }, 
      query: ` 
    mutation ($input: CreateWithdrawalInput!) {
      createWithdrawal(input: $input) {
        success code message    
        withdrawal {
          id status amount currency
          sender {
            firstName lastName companyName    
          }  
        }
      }
    }`,
    };
     mutation($input: CreateWithdrawalInput!) {
      createWithdrawal(input: $input) {
        success
        code
        message
        withdrawal {
          id
          status
          amount
          currency
          sender {
            firstName 
            lastName 
            companyName    
          }
        }
      }
    }
     { 
        "input": {
          "amount": 500,
          "currency": "AUD",
          "externalReference": "invoice #123",
          "recipient": {
            "bsb": "370370",
            "accountNo": "123123123",
            "companyName": "Acme Pty Ltd",
            "currency": "AUD",
            "accountIdType": "BSB",
              "address": {
                "street": "1 Main St SYDNEY NSW 2000",
                "country": "AU"
              }
           },
          "externalId": "1234567890",
          "idempotencyKey": "0987654321"
        }
    }
    {
      "data": {
        "createWithdrawal": {
          "success": true,
          "code": "SUCCESS",
          "message": "Withdrawal was created",
          "withdrawal": {
            "id": "67cb69f2ee6c254315bb1c3d",
            "status": "INITIALISED",
            "amount": 500,
            "currency": "AUD",
            "sender": {
              "firstName": "John",
              "lastName": "Smith",
              "companyName": "Smith Consulting Pty Ltd"
          }
        }
      }
    }
    mutation($input: CreateWithdrawalInput!) {
      createWithdrawal(input: $input) {
        success
        code
        message
        withdrawal {
          id
          status
          amount
          currency
        }
      }
    }

    Recipients

    CRUD queries for your payment recipients

    We are legally obliged to collect the actual recipient details. Please, do not send us an intermediate organisation details such as exchanges, banks, gateways, etc.

    Please, send us the final funds recipient. If sending to self then please provide your own details. See the DOCS in Playgroundarrow-up-right for other recipient details options.

    • recipient and recipients queries - read your address book.

    • createRecipient - creates a new record in the Flash Payments database.

    • updateRecipient - updates an existing recipient.

    • deleteRecipient - deletes an existing recipient.

    hashtag
    Query a single recipient

    hashtag
    Query multiple recipients

    hashtag
    Create a recipient

    circle-info

    In addresses the suburb field is an Australian suburb. For other countries you should put the city (e.g. Manila or London) or any other small administrative area name.

    If you find it technically challenging to submit all components of the recipients’s address, we would appreciate it if you could at least collect the recipients’s country along with a complete address string that includes the postcode and put them into the country and street fields, respectively. In this case, you can skip the postcode, suburb, and state

    hashtag
    Create an Individual recipient

    hashtag
    Create a Company recipient

    hashtag
    Update recipient

    circle-info

    Please note the recipient'saccountIdTypecan't be changed

    hashtag
    Delete recipient

    Senders

    CRUD queries for your payment senders

    We are legally obliged to collect the actual sender details. Please, do not send us an intermediate organisation details such as exchanges, banks, gateways, etc.

    If you want to receive funds from yourself then please provide your own details. See the DOCS in for other sender details options.

    • sender and senders queries - read your address book.

    fields, and the recipient record will still be created.

    Please note that the street field is mandatory for Australian addresses.

    {
      "input": "6b04c62ec0bf606bf216ae21"
    }
    const bodyJSON = {
      variables: {
        input: "6b04c62ec0bf606bf216ae21",
      },
      query: `
    query ($input: ID) {
      recipient(id: $input) {
        accountIdType currency country email
      }
    }`,
    };
    query($input: ID) {
      recipient(id: $input) {
        accountIdType
        currency
        country
        email
        # there are many other properties
      }
    }
    {
      "data": {
        "recipient": {
          "accountIdType": "ACC NO",
          "currency": "USD",
          "country": "AU",
          "email": "[email protected]"
        }
      }
    }
    const bodyJSON = {
      variables: {
        input: {
          currency: "USD",
        },
      },
      query: `
    query ($input: RecipientQueryInput!) {
      recipients(input: $input) {
        accountIdType currency country email
      } 
    }`,
    };
    query($input: RecipientQueryInput!) {
      recipients(input: $input) {
        accountIdType
        currency
        country
        email
        # there are many other properties
      }
    }
    {
      "input": { 
        "currency": "USD"
      }
    }  
    {
      "data": {
        "recipients": [
          {
            "accountIdType": "ACC NO",
            "currency": "USD",
            "country": "AU",
            "email": "[email protected]"
          }
        ]
      }
    }
    const bodyJSON = {
      variables: {
        input: {
          firstName: "John",
          lastName: "Malkovich",
          dob: "1987-06-05",
          accountIdType: "BSB",
          currency: "AUD",
          bsb: "370370",
          accountNo: "12341234",
          email: "[email protected]",
          address: {
            street: "22 Woolooware Rd",
            suburb: "Woolooware",
            state: "NSW",
            country: "AU",
            postcode: "2230",
          },
        },
      },
      query: `
    mutation ($input: RecipientInput!) {
      createRecipient(input: $input) {
        success code message 
        recipient {
          id nickName accountIdType currency email
        }
      }
    }`,
    };
    mutation($input: RecipientInput!) {
      createRecipient(input: $input) {
        success code message
        recipient {
          id nickName accountIdType currency email
          # there are many other properties
        }
      }
    }
     {
      "input": { 
        "firstName": "John",
        "lastName": "Malkovich",
        "dob": "1987-06-05",
        "accountIdType": "BSB",
        "currency": "AUD",
        "bsb": "370370",
        "accountNo": "12341234",
        "email": "[email protected]",
        "address": {
          "street": "22 Woolooware Rd",
          "suburb": "Woolooware",
          "state": "NSW",
          "country": "AU",
          "postcode": "2230"
        }
      }
    }
    {
      "data": {
        "createRecipient": {
          "success": true,
          "code": "SUCCESS",
          "message": "Recipient created",
          "recipient": {
            "id": "6859c06eaa36ba8534d974f1",
            "nickName": "JohnMalkov",
            "accountIdType": "BSB",
            "currency": "AUD",
            "email": "[email protected]"
          }
        }
      }
    }
    const bodyJSON = {
      variables: {
        input: {
          companyName: "Acme Pty Ltd",
          accountIdType: "BSB",
          currency: "AUD",
          bsb: "370370",
          accountNo: "12341234",
          email: "[email protected]",
          address: {
            street: "22 Woolooware Rd",
            suburb: "Woolooware",
            state: "NSW",
            country: "AU",
            postcode: "2230",
          },
        },
      },
      query: `
    mutation ($input: RecipientInput!) {
      createRecipient(input: $input) {
        success code message 
        recipient {
          id nickName accountIdType currency email
        }
      }
    }`,
    };
    mutation($input: RecipientInput!) {
      createRecipient(input: $input) {
        success code message
        recipient {
          id nickName accountIdType currency email
          # there are many other properties
        }
      }
    }
     {
      "input": { 
        "companyName": "Acme Pty Ltd",
        "accountIdType": "BSB",
        "currency": "AUD",
        "bsb": "370370",
        "accountNo": "12341234",
        "email": "[email protected]",
        "address": {
          "street": "22 Woolooware Rd",
          "suburb": "Woolooware",
          "state": "NSW",
          "country": "AU",
          "postcode": "2230"
        }
      }
    }
    {
      "data": {
        "createRecipient": {
          "success": true,
          "code": "SUCCESS",
          "message": "Recipient created",
          "recipient": {
            "id": "6859ca4baa36ba8534d97da1",
            "nickName": "Acme Pty L",
            "accountIdType": "BSB",
            "currency": "AUD",
            "email": "[email protected]"
          }
        }
      }
    }
    const bodyJSON = {
      variables: {
        id: "5ba89a6b35a2b327b81ffc3b",
        input: {
          nickName: "JohnM",
          firstName: "John",
          lastName: "Malkovich",
          accountIdType: "BSB",
          currency: "AUD",
          bsb: "370370",
          accountNo: "12341234",
          email: "[email protected]",
          address: {
            street: "22 Woolooware Rd",
            suburb: "Woolooware",
            state: "NSW",
            country: "AU",
            postcode: "2230",
          },
        },
      },
      query: `
    mutation ($id: ID, $input: RecipientInput!) {
      updateRecipient(id: $id, input: $input) {
        success code message  
        recipient {
          id nickName    
        }
      }
    }`,
    };  
    mutation($id: ID, $input: RecipientInput!) {
      updateRecipient(id: $id, input: $input) {
        success
        code
        message
        recipient {
          id
          nickName
          # there are many other properties
        }
      }
    }
    {
      "id": "5ba89a6b35a2b327b81ffc3b",
      "input":{
        "nickName": "JohnM",
        "firstName": "John",
        "lastName": "Malkovich",
        "accountIdType": "BSB",
        "currency": "AUD",
        "bsb": "370370",
        "accountNo": "12341234",
        "email": "[email protected]",
        "address": {
          "street": "22 Woolooware Rd",
          "suburb" : "Woolooware",
          "state": "NSW",
          "country": "AU",
          "postcode": "2230"
        }
      }
    }
    {
      "data": {
        "createRecipient": {
          "success": true,
          "code": "SUCCESS",
          "message": "Recipient updated",
          "recipient": {
            "id": "5ba89a6b35a2b327b81ffc3b",
            "nickName": "JohnM"
          }
        }
      }
    }
    const bodyJSON = {
      variables: {
        input: "6b04c62ec0bf606bf216ae21",
      },
      query: `
    mutation ($input: ID) {
      deleteRecipient(id: $input) {
        success code message
      }
    }`,
    };
    mutation($input: ID) {
      deleteRecipient(id: $input) {
        success 
        code 
        message
        # there are many other properties
      }
    }
    {
      "input": "6b04c62ec0bf606bf216ae21"
    }
    {
      "data": {
        "deleteRecipient": {
          "success": true,
          "code": "SUCCESS",
          "message": "Recipient deleted"
        }
      }
    }

    createSender - creates a new record in the Flash Payments database.

  • updateSender - updates an existing sender.

  • deleteSender - deletes an existing sender.

  • hashtag
    Query single sender

    const bodyJSON = {
      variables: {
    
    query($input: ID) {
      sender(id
    
    {
      "input": "59f2733f2519e236edab0efe"
    }
    {
      "data": {
        "sender": {
          "email": "[email protected]",
          "firstName": "John",
          "lastName": "Smith",
          "companyName": null,
          "address": {
            "country": "GB"
          }
        }
      }
    }

    hashtag
    Query multiple senders

    const bodyJSON = {
      variables: {
        input: {
          email: "[email protected]",
        },
      },
      query: `
    query ($input: RecipientQueryInput!) {
      senders(input: $input) {
        email firstName lastName companyName
        address {
          country
        } 
      } 
    }`,
    };
    query($input: SenderQueryInput!) {
      senders(input: $input) {
        email
        firstName
        lastName
        companyName
        address {
          country
        }
        # there are many other properties
      }
    }
    {
      "input": {
        "email": "[email protected]" 
      }
    }
    {
      "data": {
        "senders": [
          {
            "email": "[email protected]",
            "firstName": "John",
            "lastName": "Smith",
            "companyName": null,
            "address": {
              "country": "GB"
            }
          },
          {
            "email": "[email protected]",
            "firstName": null,
            "lastName": null,
            "companyName": "Acme Inc",
            "address": {
              "country": "US"
            }
          },
        ]
      }
    }

    hashtag
    Create a sender

    circle-info

    In addresses the suburb field is an Australian suburb. For other countries you should put the city (e.g. Manila or London) or any other small administrative area name.

    If you find it technically challenging to submit all components of the sender’s address, we would appreciate it if you could at least collect the sender’s country along with a complete address string that includes the postcode and put them into the country and street fields, respectively. In this case, you can skip the postcode, suburb, and state fields, and the sender record will still be created.

    Please note that the street field is mandatory for Australian addresses.

    circle-info

    The date of birth (dob) is not mandatory. However, if it is not provided, your transactions may undergo additional compliance reviews, which can lead to longer processing times—potentially several hours or days instead of seconds. Please also be aware that this may result in additional fees to cover the extra effort involved.

    hashtag
    Create an Individual sender

    const bodyJSON = {
      variables: {
        input: {
          firstName: "Malcolm",
          lastName: "Jez",
          dob: "2000-01-01",
          email: "[email protected]",
          mobile: "+61 4123456789",
          address: {
            street: "1 Test St",
            suburb: "London",
            state: "TST",
            country: "GB",
            postcode: "2000",
          },
          idDoc: {
            type: "passport",
            docNumber: "GB1234321",
            issuer: "His Majesty’s Passport Office (HMPO)",
            issueDate: "1990-01-01",
            expiryDate: "2045-01-01",
            country: "GB",
          },
        },
      },
      query: `
    mutation ($input: SenderInput!) {
      createSender(input: $input) {
        success code message
        sender {
          id nickName
        }
      }
    }`,
    };
    mutation($input: SenderInput!) {
      createSender(input: $input) {
        success code message
        sender {
          id 
          nickName
          # there are many other properties
        }
      }
    }
    {
      "input": {
        "firstName": "Malcolm",
        "lastName": "Jez",
        "dob": "2000-01-01",
        "email": "[email protected]",
        "mobile": "+61 4123456789", 
        "address": {
          "street": "1 Test St", 
          "suburb": "London", 
          "state": "TST", 
          "country": "GB", 
          "postcode": "2000"
        },
        "idDoc": {
          "type": "passport", 
          "docNumber": "GB1234321", 
          "issuer": "His Majesty’s Passport Office (HMPO)", 
          "issueDate": "1990-01-01", 
          "expiryDate": "2045-01-01", 
          "country": "GB"
        }
      }
    }
    {
      "data": {
        "createSender": {
          "success": true,
          "code": "CREATED",
          "message": "New sender created",
          "sender": {
            "id": "686393e689c1fb1b255cac5c",
            "nickName": "MalcolmJez"
          }
        }
      }
    }

    hashtag
    Create a Company sender

    const bodyJSON = {
      variables: {
        input: {
          companyName: "Acme Pte Ltd",
          businessNumber: "12345678912",
          email: "[email protected]",
          mobile: "+61 4123456789",
          address: {
            street: "1 Test St",
            suburb: "London",
            state: "TST",
            country: "GB",
            postcode: "2000",
          },
          idDoc: {
            type: "certificateOfRegistration",
            docNumber: "GB-REG-987654321",
            issuer: "Companies House",
            issueDate: "1990-01-01",
            expiryDate: "2100-01-01",
            country: "GB",
          },
        },
      },
      query: `
    mutation ($input: SenderInput!) {
      createSender(input: $input) {
        success code message 
        sender { 
          id nickName    
        }  
      }
    }`,
    };
    mutation($input: SenderInput!) {
      createSender(input: $input) {
        success code message
        sender {
          id 
          nickName
          # there are many other properties
        }
      }
    }
    {
      "input": {
        "companyName": "Acme Pte Ltd", 
        "businessNumber": "12345678912", 
        "email": "[email protected]", 
        "mobile": "+61 4123456789", 
        "address": {
          "street": "1 Test St", 
          "suburb": "London", 
          "state": "TST", 
          "country": "GB", 
          "postcode": "2000"
        },
        "idDoc": {
          "type": "certificateOfRegistration", 
          "docNumber": "GB-REG-987654321", 
          "issuer": "Companies House", 
          "issueDate": "1990-01-01", 
          "expiryDate": "2100-01-01", 
          "country": "GB"
        }
      }
    }
    {
      "data": {
        "createSender": {
          "success": true,
          "code": "CREATED",
          "message": "New sender created",
          "sender": {
            "id": "68638e6989c1fb1b255ca9c3",
            "nickName": "Acme Pte L"
          }
        }
      }
    }

    hashtag
    Update sender

    const bodyJSON = {
      variables: {
        input: {
          firstName: "Malcolm",
          lastName: "Jez The Second",
          dob: "2000-01-01",
          email: "[email protected]",
          mobile: "+61 4123456789",
          address: {
            street: "1 Test St",
            suburb: "London",
            state: "TST",
            country: "GB",
            postcode: "2000",
          },
        },
      },
      query: `
    mutation ($input: SenderInput!) {
      updateSender(input: $input) {
        success code message
        sender {
          id lastName
        }
      }
    }`,
    };
    mutation($id: ID, $input: SenderInput!) {
      updateSender(id: $id, input: $input) {
        success code message
        sender {
          id 
          lastName
          # there are many other properties
        }
      }
    }
    {
      "id": "686393e689c1fb1b255cac5c",
      "input": {
        "firstName": "Malcolm",
        "lastName": "Jez The Second",
        "dob": "2000-01-01",
        "email": "[email protected]",
        "mobile": "+61 4123456789", 
        "address": {
          "street": "1 Test St", 
          "suburb": "London", 
          "state": "TST", 
          "country": "GB", 
          "postcode": "2000"
        }
      }
    }
    {
      "data": {
        "updateSender": {
          "success": true,
          "code": "UPDATED",
          "message": "Sender 686393e689c1fb1b255cac5c updated.",
          "sender": {
            "id": "686393e689c1fb1b255cac5c",
            "lastName": "Jez The Second"
          }
        }
      }
    }

    hashtag
    Delete sender

    const bodyJSON = {
      variables: {
        input: "686393e689c1fb1b255cac5c",
      },
      query: `
    mutation ($input: ID) {
      deleteSender(id: $input) {
        success code message
      }
    }`,
    };
    mutation($input: ID) {
      deleteSender(id: $input) {
        success 
        code 
        message
        # there are many other properties
      }
    }
    {
      "input": "686393e689c1fb1b255cac5c"
    }
    
    {
      "data": {
        "deleteSender": {
          "success": true,
          "code": "SUCCESS",
          "message": "Sender deleted"
        }
      }
    }
    Playgroundarrow-up-right
    input: "59f2733f2519e236edab0efe",
    },
    query: `
    query ($input: ID) {
    sender(id: $input) {
    email firstName lastName companyName
    address {
    country
    }
    }
    }`,
    };
    :
    $input
    )
    {
    email
    firstName
    lastName
    companyName
    address {
    country
    }
    # there are many other properties
    }
    }

    Webhooks

    Two types of the webhooks

    The primary triggers for all webhooks are status changes in payments, withdrawals, deposits, or conversions. For example, a webhook is sent when a withdrawal status changes from PENDING to CONFIRMED.

    There are two types of webhooks in Flash Payments.

    • Regular webhooks - a URL would need to be saved to your FlashConnectarrow-up-right settings. Supports all types of events.

      • You can browse the history of all the webhook HTTP requests and your server responses, their JSON bodies and headers.

      • If there is no response we will show you what exactly the problem is: DNS issue, networking issue, 5XX response, etc.

      • You can receive webhooks when a deposit lands to your Virtual Account Number (VAN).

    • - you would need to provide a callback URL per each payment/withdrawal/conversion while creating them.

    The webhooks HTTP POST calls will follow all the (3XX codes).

    hashtag
    Security

    hashtag
    Cryptographic signature

    All webhook HTTP requests carry a cryptographic signature. and do it slightly different though.

    hashtag
    Headers

    Each request will contain at least these 4 headers:

    hashtag
    Flash Payments webhook request IP address

    All webhook HTTP requests would be coming from these IP addresses:

    • UAT environment: 52.64.185.170 and 13.210.129.208

    • Production environment: 52.62.138.234 and 52.65.3.195

    hashtag
    Example payloads

    Deposits

    chevron-rightdeposit_initiatedhashtag
    chevron-rightdeposit_reviewinghashtag
    chevron-rightdeposit_clearedhashtag
    chevron-rightdeposit_cancelledhashtag
    chevron-rightdeposit_refundinghashtag
    chevron-rightdeposit_refundedhashtag

    Withdrawals

    chevron-rightwithdrawal_initiatedhashtag
    chevron-rightwithdrawal_reviewinghashtag
    chevron-rightwithdrawal_pendinghashtag
    chevron-rightwithdrawal_completedhashtag
    chevron-rightwithdrawal_failedhashtag
    chevron-rightwithdrawal_refundedhashtag
    chevron-rightwithdrawal_cancelledhashtag

    Payments

    chevron-rightcurrency_convertedhashtag
    chevron-rightpayment_completehashtag
    chevron-rightpayment_failedhashtag
    chevron-rightpayment_cancelledhashtag
    chevron-rightpayment_createdhashtag

    Conversions

    chevron-rightconversion_initialisedhashtag
    chevron-rightconversion_pendinghashtag
    chevron-rightconversion_convertedhashtag
    chevron-rightconversion_failedhashtag
    chevron-rightconversion_cancelledhashtag

    Sub-clients

    chevron-rightsubclient_initiatedhashtag
    chevron-rightsubclient_activehashtag
    chevron-rightsubclient_unapprovedhashtag
    chevron-rightsubclient_failed_kychashtag
    chevron-rightsubclient_deactivatedhashtag
    chevron-rightsubclient_disabledhashtag

    Adverse Media Search

    chevron-rightams_initialisedhashtag
    chevron-rightams_pendinghashtag
    chevron-rightams_completedhashtag
    chevron-rightams_failedhashtag
    Ad hoc webhooks
    standard HTTP redirectsarrow-up-right
    Ad hoc
    regular webhooks
    content-type: application/json
    user-agent: FlashFX
    flashfx-request-id: [A unique ID of this particuar event]
    flashfx-signature: [The cryptographic signature]
    {
      "event": "deposit_initiated",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "603f0198770d6595e3c83e0d",
      "amount": 100,
      "totalFee": 1,
      "currency": "AUD",
      "externalReference": "2233445566",
      "clearedAt": "2026-03-03T03:25:12.792Z",
      "statusMessage": "Deposit initiated",
      "recipient": {
        "accountName": "ACME Inc",
        "accountNo": "1839394",
        "bsb": "809387"
      },
      "sender": {
        "accountName": "ACME Inc",
        "companyName": "ACME Inc",
        "bankName": "Bank ACME",
        "bankCountry": "AU"
      },
      "subClient": {
        "id": "203af01936410fd5d5e3c8f14d",
        "fullName": "ACME Inc",
        "accountNo": "1839394",
        "bsb": "809387",
        "externalId": "111222333"
      }
    }
    {
      "event": "deposit_reviewing",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "603f0198770d6595e3c83e0d",
      "amount": 100,
      "totalFee": 1,
      "currency": "AUD",
      "externalReference": "2233445566",
      "clearedAt": "2026-03-03T03:25:12.792Z",
      "statusMessage": "Awaiting manual compliance",
      "recipient": {
        "accountName": "ACME Inc",
        "accountNo": "1839394",
        "bsb": "809387"
      },
      "sender": {
        "accountName": "ACME Inc",
        "companyName": "ACME Inc",
        "bankName": "Bank ACME",
        "bankCountry": "AU"
      },
      "subClient": {
        "id": "203af01936410fd5d5e3c8f14d",
        "fullName": "ACME Inc",
        "accountNo": "1839394",
        "bsb": "809387",
        "externalId": "111222333"
      }
    }
    {
      "event": "deposit_cleared",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "603f0198770d6595e3c83e0d",
      "amount": 100,
      "totalFee": 1,
      "currency": "AUD",
      "externalReference": "2233445566",
      "clearedAt": "2026-03-03T03:25:12.792Z",
      "statusMessage": "Deposit cleared",
      "recipient": {
        "accountName": "ACME Inc",
        "accountNo": "1839394",
        "bsb": "809387"
      },
      "sender": {
        "accountName": "ACME Inc",
        "companyName": "ACME Inc",
        "bankName": "Bank ACME",
        "bankCountry": "AU"
      },
      "subClient": {
        "id": "203af01936410fd5d5e3c8f14d",
        "fullName": "ACME Inc",
        "accountNo": "1839394",
        "bsb": "809387",
        "externalId": "111222333"
      }
    }
    {
      "event": "deposit_cancelled",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "603f0198770d6595e3c83e0d",
      "amount": 100,
      "totalFee": 1,
      "currency": "AUD",
      "externalReference": "2233445566",
      "clearedAt": "2026-03-03T03:25:12.792Z",
      "statusMessage": "Cancelled by: [email protected] : ",
      "recipient": {
        "accountName": "ACME Inc",
        "accountNo": "1839394",
        "bsb": "809387"
      },
        "sender": {
        "accountName": "ACME Inc",
        "companyName": "ACME Inc",
        "bankName": "Bank ACME",
        "bankCountry": "AU"
      },
      "subClient": {
        "id": "203af01936410fd5d5e3c8f14d",
        "fullName": "ACME Inc",
        "accountNo": "1839394",
        "bsb": "809387",
        "externalId": "111222333"
      }
    }
    {
      "event": "deposit_refunding",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "603f0198770d6595e3c83e0d",
      "amount": 100,
      "totalFee": 1,
      "refundAmount": 99,
      "currency": "AUD",
      "externalReference": "2233445566",
      "refundReason": "Client refund request",
      "statusMessage": "Deposit refunded",
      "refundedAt": "2026-03-03T03:28:43.936Z",
      "clearedAt": "2026-03-03T03:25:12.792Z",
      "recipient": {
        "accountName": "ACME Inc",
        "accountNo": "1839394",
        "bsb": "809387"
      },
        "sender": {
        "accountName": "ACME Inc",
        "companyName": "ACME Inc",
        "bankName": "Bank ACME",
        "bankCountry": "AU"
      },
      "subClient": {
        "id": "203af01936410fd5d5e3c8f14d",
        "fullName": "ACME Inc",
        "accountNo": "1839394",
        "bsb": "809387",
        "externalId": "111222333"
      }
    }
    {
      "event": "deposit_refunded",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "603f0198770d6595e3c83e0d",
      "amount": 100,
      "totalFee": 1,
      "refundAmount": 99,
      "currency": "AUD",
      "externalReference": "2233445566",
      "refundReason": "Client refund request",
      "statusMessage": "Deposit refunded",
      "refundedAt": "2026-03-03T03:28:43.936Z",
      "clearedAt": "2026-03-03T03:25:12.792Z",
      "recipient": {
        "accountName": "ACME Inc",
        "accountNo": "1839394",
        "bsb": "809387"
      },
        "sender": {
        "accountName": "ACME Inc",
        "companyName": "ACME Inc",
        "bankName": "Bank ACME",
        "bankCountry": "AU"
      },
      "subClient": {
        "id": "203af01936410fd5d5e3c8f14d",
        "fullName": "ACME Inc",
        "accountNo": "1839394",
        "bsb": "809387",
        "externalId": "111222333"
      }
    }
    {
      "event": "withdrawal_initiated",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "51711af8c078ba061f623531",
      "amount": 2000,
      "totalFee": 1,
      "currency": "AUD",
      "externalId": "12344321",
      "subClient": {
        "id": "203af01936410fd5d5e3c8f14d",
        "fullName": "ACME Inc",
        "accountNo": "1839394",
        "bsb": "809387",
        "externalId": "111222333"
      }
    }
    {
      "event": "withdrawal_reviewing",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "51711af8c078ba061f623531",
      "amount": 2000,
      "totalFee": 1,
      "currency": "AUD",
      "statusMessage": "Awaiting manual compliance"
      "externalId": "12344321",
      "subClient": {
        "id": "203af01936410fd5d5e3c8f14d",
        "fullName": "ACME Inc",
        "accountNo": "1839394",
        "bsb": "809387",
        "externalId": "111222333"
      }
    }
    {
      "event": "withdrawal_pending",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "51711af8c078ba061f623531",
      "amount": 2000,
      "totalFee": 1,
      "currency": "AUD",
      "statusMessage": "Sent to recipient bank"
      "externalId": "12344321",
      "subClient": {
        "id": "203af01936410fd5d5e3c8f14d",
        "fullName": "ACME Inc",
        "accountNo": "1839394",
        "bsb": "809387",
        "externalId": "111222333"
      }
    }
    {
      "event": "withdrawal_completed",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "51711af8c078ba061f623531",
      "amount": 2000,
      "totalFee": 1,
      "currency": "AUD",
      "externalId": "12344321",
      "statusMessage": "Transaction Confirmed",
      "clearedAt": "2021-03-03T03:25:12.792Z",
      "subClient": {
        "id": "203af01936410fd5d5e3c8f14d",
        "fullName": "ACME Inc",
        "accountNo": "1839394",
        "bsb": "809387",
        "externalId": "111222333"
      }
    }
    {
      "event": "withdrawal_failed",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "51711af8c078ba061f623531",
      "amount": 2000,
      "totalFee": 1,
      "currency": "AUD",
      "externalId": "12344321",
      "subClient": {
        "id": "203af01936410fd5d5e3c8f14d",
        "fullName": "ACME Inc",
        "accountNo": "1839394",
        "bsb": "809387",
        "externalId": "111222333"
      }
    }
    {
      "event": "withdrawal_refunded",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "51711af8c078ba061f623531",
      "amount": 2000,
      "totalFee": 1,
      "refundAmount": 2000,
      "currency": "AUD",
      "externalId": "12344321",
      "refundReason": "No account or incorrect account number",
      "statusMessage": "Payout reversal",
      "refundedAt": "2026-03-04T15:21:11.920Z",
      "clearedAt": "2026-03-03T03:25:12.792Z",
      "recipient": {
        "displayName": "John Smith",
        "bsb": "012620",
        "accountNo": "89900998"
      },
      "subClient": {
        "id": "203af01936410fd5d5e3c8f14d",
        "fullName": "John Smith",
        "accountNo": "1839394",
        "bsb": "809387",
        "externalId": "111222333"
      }
    }
    {
      "event": "withdrawal_cancelled",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "51711af8c078ba061f623531",
      "amount": 2000,
      "totalFee": 1,
      "currency": "AUD",
      "externalId": "12344321",
      "rejectCode": "CANCELLATION_REQUESTED_BY_PARTICIPANT",
      "rejectedAt": "2025-07-24T21:41:14.581Z"
      "statusMessage": "The transaction is rejected upon request.",
      "subClient": {
        "id": "203af01936410fd5d5e3c8f14d",
        "fullName": "ACME Inc",
        "accountNo": "1839394",
        "bsb": "809387",
        "externalId": "111222333"
      }
    }
    {
      "event": "currency_converted",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "60711af8c078ba061f623531",
      "fromAmount": 1000,
      "fromCurrency": "AUD",
      "toAmount": 411.04,
      "toCurrency": "EUR",
      "externalId": "12344321"
    }
    {
      "event": "payment_complete",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "60711af8c078ba061f623531",
      "fromAmount": 1000,
      "fromCurrency": "AUD",
      "toAmount": 411.04,
      "toCurrency": "EUR",
      "externalId": "12344321"
    }
    {
      "event": "payment_failed",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "60711af8c078ba061f623531",
      "fromAmount": 1000,
      "fromCurrency": "AUD",
      "toAmount": 411.04,
      "toCurrency": "EUR",
      "externalId": "12344321"
    }
    {
      "event": "payment_cancelled",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "60711af8c078ba061f623531",
      "fromAmount": 1000,
      "fromCurrency": "AUD",
      "toAmount": 411.04,
      "toCurrency": "EUR",
      "externalId": "12344321"
    }
    {
      "event": "payment_created",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "60711af8c078ba061f623531",
      "fromAmount": 3500,
      "fromCurrency": "EUR",
      "toAmount": 2501.94,
      "toCurrency": "AUD",
      "subClient": {
        "id": "203af01936410fd5d5e3c8f14d",
        "fullName": "ACME Inc",
        "accountNo": "1839394",
        "bsb": "809387",
        "externalId": "111222333"
      }
    }
    {
      "event": "conversion_initialised",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "60711af8c078ba061f623531",
      "fromAmount": 1000,
      "fromCurrency": "AUD",
      "toAmount": 411.04,
      "toCurrency": "EUR",
      "rate": 0.41104,
      "externalId": "12344321"
    }
    {
      "event": "conversion_pending",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "60711af8c078ba061f623531",
      "fromAmount": 1000,
      "fromCurrency": "AUD",
      "toAmount": 411.04,
      "toCurrency": "EUR",
      "rate": 0.41104,
      "externalId": "12344321"
    }
    {
      "event": "conversion_converted",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "60711af8c078ba061f623531",
      "fromAmount": 1000,
      "fromCurrency": "AUD",
      "toAmount": 411.04,
      "toCurrency": "EUR",
      "rate": 0.41104,
      "externalId": "12344321"
    }
    {
      "event": "conversion_failed",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "60711af8c078ba061f623531",
      "fromAmount": 1000,
      "fromCurrency": "AUD",
      "toAmount": 411.04,
      "toCurrency": "EUR",
      "rate": 0.41104,
      "externalId": "12344321"
    }
    {
      "event": "conversion_cancelled",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "60711af8c078ba061f623531",
      "fromAmount": 1000,
      "fromCurrency": "AUD",
      "toAmount": 411.04,
      "toCurrency": "EUR",
      "rate": 0.41104,
      "externalId": "12344321"
    }
    {
      "event": "subclient_initiated",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "695257f8c8754a74ad671c48",
      "fullName": "John Doe",
      "status": "INITIATED",
      "externalId": "123456789"
    }
    {
      "event": "subclient_active",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "695257f8c8754a74ad671c48",
      "fullName": "John Doe",
      "status": "ACTIVE",
      "externalId": "123456789"
    }
    {
      "event": "subclient_unapproved",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "695257f8c8754a74ad671c48",
      "fullName": "John Doe",
      "status": "UNAPPROVED",
      "externalId": "123456789"
    }
    {
      "event": "subclient_failed_kyc",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "695257f8c8754a74ad671c48",
      "fullName": "John Doe",
      "status": "FAILED_KYC",
      "externalId": "123456789"
    }
    {
      "event": "subclient_deactivated",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "695257f8c8754a74ad671c48",
      "fullName": "John Doe",
      "status": "DEACTIVATED",
      "externalId": "123456789"
    }
    {
      "event": "subclient_disabled",
      "eventScheduledAt": "2026-03-03T01:25:11.984Z",
      "id": "695257f8c8754a74ad671c48",
      "fullName": "John Doe",
      "status": "DEACTIVATED",
      "externalId": "123456789"
    }
    {
      "event": "ams_initialised",
      "eventScheduledAt": "2026-03-03T08:23:14.521Z",
      "id": "6820a4f3e1c2b5d8f0123456",
      "name": "John Smith",
      "country": "AU",
      "status": "INITIALISED"
    }
    {
      "event": "ams_pending",
      "eventScheduledAt": "2026-03-03T08:23:15.108Z",
      "id": "6820a4f3e1c2b5d8f0123456",
      "name": "John Smith",
      "country": "AU",
      "status": "PENDING"
    }
    {
      "event": "ams_completed",
      "eventScheduledAt": "2026-03-03T08:26:42.774Z",
      "id": "6820a4f3e1c2b5d8f0123456",
      "name": "John Smith",
      "country": "AU",
      "status": "COMPLETED"
    }
    {
      "event": "ams_failed",
      "eventScheduledAt": "2026-03-03T08:26:42.774Z",
      "id": "6820a4f3e1c2b5d8f0123456",
      "name": "John Smith",
      "country": "AU",
      "status": "FAILED"
    }

    API change log

    History of changes to this API schema

    hashtag
    2026-04-14

    hashtag
    Added

    New Adverse Media Search (AMS) API. You can now screen individuals and organisations against web-based adverse media sources directly via the API.

    • New mutation — submits a search for an individual or organisation. The scan runs in the background; use the returned id to track progress.

    • New and queries — retrieves your AMS requests with optional filters by status, date range, name, and country.

    • Four new : ams_initialised, ams_pending

    Please contact support to have this API enabled for your account.

    hashtag
    2026-04-10

    hashtag
    Added

    New mutation. Confirmation of Payee (CoP) is a name-verification service for Australian domestic accounts. You can use it to check whether the recipient's name matches the account details held by their financial institution. The service currently supports Australian BSB accounts.

    hashtag
    2026-03-18

    hashtag
    Added

    Two new objects to mutation. You can change a sub-client's address and postalAddress. The updated address will be re-verified, so please make sure to include all its components, even if some fields, like the country, remain unchanged.

    hashtag
    2026-03-05

    hashtag
    Added

    New rail and railService properties to Withdrawal and Deposit payloads. You can now see exactly which payment infrastructure (such as NPP or BECS) and specific schemes (such as NPP IFTI) are used to route your transactions.

    hashtag
    2026-03-03

    hashtag
    Added

    New currnecy property to the StatementQueryInput, which allows you to retrieve any currency balance, not just the default AUD.

    hashtag
    2026-02-26

    hashtag
    Added

    New eventScheduledAt property to all payloads.

    hashtag
    2025-12-31

    hashtag
    Added

    New sub-client (aka Virtual Account Number, VAN) .

    Previously a sub-client could be in 2 statuses: ACTIVE and DEACTIVATED.

    Now there are 6: INITIATED, ACTIVE, UNAPPROVED, DEACTIVATED, FAILED_KYC, DISABLED.

    A set of new webhook events become available. See . A webhook is sent when a sub-client status gets changed.

    hashtag
    2025-12-30

    hashtag
    Added

    A new rejectCode when we your payout - SOURCE_OF_FUNDS_INADEQUATE. You'll receive it if we sent you an RFI (request for information) but your response contained a low quality data.

    Please note, that a sibling property statusMessage will be hand crafted so that you know what exactly is wrong with your RFI reply (within the legal bounds). Please use the text to improve your KYC processes.

    hashtag
    2025-11-14

    hashtag
    Added

    A new rejectCode when we your payout - DATA_ENQUIRY_RESPONSE_INADEQUATE. You'll receive it if we sent you an RFI (request for information) but your response contained a low quality data.

    Please note, that a sibling property statusMessage will be hand crafted so that you know what exactly is wrong with your RFI reply (within the legal bounds). Please use the text to improve your KYC processes.

    hashtag
    2025-11-10

    hashtag
    Added

    The FX Payments createPayment can accept sender and recipient as JSON objects now too.

    This means that when you need to do an orchestrated FX payment you need to submit only one HTTP request (createPayment) instead of 3 (createSender, createRecipient, and createPayment).

    hashtag
    2025-10-31

    hashtag
    Added

    A high demand long awaited feature. You don't need to pre-create senders/recipients before submitting a payout using createWithdrawal .

    This means that when you need to do a remittance payment (aka payout) you need to submit only one HTTP request (createWithdrawal) instead of 3 (createSender, createRecipient, and createWithdrawal).

    Example:

    hashtag
    2025-10-24

    hashtag
    Changed

    Enum WithdrawalReason is renamed to TransactionReason. The reason field inside CreateWithdrawalInput and Withdrawal type now uses TransactionReason instead of WithdrawalReason.

    hashtag
    2025-08-07

    hashtag
    Changed

    The validation logic for the bic field in the createRecipient mutation has been relaxed:

    • When accountIdType is set to IBAN, BSB, or PAYID, the bic field is not required any more.

    • When accountIdType is set to ABA

    hashtag
    2025-07-26

    hashtag
    Added

    Three new fields to the Withdrawal type:

    • clearedAt - the timestamp when the withdrawal become CONFIRMED.

    • rejectedAt - the timestamp when the it was rejected by Flash Payments. See the rejectCode and statusMessage fields to understand the rejection reason.

    hashtag
    2025-07-25

    hashtag
    Added

    The new optional field called reason was added to the createWithdrawal mutation and Withdrawal type.

    If you have a payment/transaction/payout purpose - you must submit it to us via the API. See all the possible purpose codes (aka reason values) in the (click the link in the header of this website), look inside the "docs" by the word "reason". You need to find the GraphQL enum called WithdrawalReason.

    hashtag
    2025-07-24

    hashtag
    Added

    An optional affiliation field has been added to the login mutation. This field accepts the Affiliation enum values FP_AUS or FP_LUX, allowing users to specify which Flash Payments subsidiary account to access when multiple contractual agreements exist. It is only required if your have more than one such agreement with us.

    hashtag
    2025-05-02

    hashtag
    Removed (BREAKING)

    Removed depositDetails query as deprecated and non-functioning since March 2024.

    hashtag
    2025-01-24

    hashtag
    Changed

    Improved validation rules for the following mutations: , , , , , and Affected fields: idDoc.docNumber idDoc.issuer legalName businessNumber legalName externalId. These fields allow only the ASCII characters now.

    Also, the first, last, and middle names are limited to 75 chars now.

    Also, FQDN-like names will be rejected. Examples: "Aaron x.com", "Ben.eu", "Visit as at URL:example.com/about", etc.

    hashtag
    2025-01-18

    hashtag
    Added

    New fields have been added to the , , and mutations. You can now provide idDoc.country, idDoc.issueDate, and idDoc.expiryDate. The idDoc.issuer field now only stores additional information about the issuer, while idDoc.country holds the country code of the country that issued the document. To avoid creating a breaking change, we currently allow you to provide idDoc.country and/or idDoc.issuer. In the future, we plan to make idDoc.country a required field.

    hashtag
    2024-12-09

    hashtag
    Added

    New mutation. You can change a sub-client's externalId now, but nothing else.

    hashtag
    2024-10-22

    hashtag
    Added

    New the feature.

    • New mutation createConversion. New queries conversion and conversions.

    • The FromCurrency enum used to have only one item AUD. Now there are 8: AUD CAD CHF EUR GBP NZD SGD USD.

    hashtag
    2024-10-11

    hashtag
    Fixed

    The bankInfo was not returning information about BICs and IBANs. It works now.

    hashtag
    2024-10-01

    hashtag
    Changed (BREAKING)

    Improved validation of recipient, sender, withdrawal, institution related mutations. From now on email, companyName, legalName, businessNumber, externalReference must include only the ASCII characters.

    hashtag
    2024-05-18

    hashtag
    Removed (BREAKING)

    Removed AccountIdType.PH_CASH, Recipient.phCashoutNetwork with RecipientInput.phCashoutNetwork and the corresponding enum type PhCashoutNetwork from the GraphQL schema. These were not working for more than a year.

    hashtag
    2024-05-17

    hashtag
    Removed (BREAKING)

    Removed AccountIdType.RIPPLE, Recipient.rippleAddress with Recipient.destTag from the GraphQL schema. These were deprecated 2.5 years ago.

    hashtag
    2024-04-16

    hashtag
    Removed (BREAKING)

    Removed Sender.isRipple and CurrencyIso3.XRP from the GraphQL schema. These were deprecated 2.5 years ago.

    hashtag
    2024-03-13

    hashtag
    Added

    New introduced for rejected (aka cancelled) withdrawals. When withdrawals you can clearly see why using the new rejectCode and statusMessage. Available in the Withdrawal type and sent to your application via the webhook.

    hashtag
    2024-02-05

    hashtag
    Changed

    Improved to respond with appropriate error message when trying to change the recipient's accountIdType which is not allowed by design.

    hashtag
    2023-11-01

    hashtag
    Added

    Added to the CreateWithdrawalInput.

    hashtag
    2023-10-25

    hashtag
    Removed (BREAKING)

    • Fields acceptingInstructionInstitutionSenderId and acceptingMoneyInstitutionSenderId were removed from the CreateWithdrawalInput.

    hashtag
    Added

    • Instead instructingInstitutionId was added. (A new API for creating "institutions" is coming soon, but at the moment they can be created via the Flash Connect.)

    hashtag
    2023-08-22

    hashtag
    Added

    • query.

      • This query returns the same data as the Download CSV button on the Account Statement page of the . It explains every change of you primary balance.

      • Currently it returns exactly 1 day of data. We plan to make date range selection more flexible in the future.

    hashtag
    2023-08-04

    hashtag
    Changes

    • Changed links from to domain. Old domain will continue working unit future notice.

    hashtag
    2023-07-28

    hashtag
    Changes

    • Our system always allowed accountNo to have letter. However, our API forced digits only. So, from now on, when you use createRecipient, your accountNo can have both letters and digits.

    hashtag
    2023-05-25

    hashtag
    Changes

    • Improved mobile phone validation. Now if mobile starts with "00" it's treated as if it starts with "+".

    • Quote size accepts positive numbers only.

    hashtag
    Changes (BREAKING)

    • The recipient.mobile and sender.mobile can accept only valid international phone numbers.

    hashtag
    2023-03-15

    hashtag
    Added

    • Added the withdrawal_pending . Invoked after the transaction is sent to the recipient bank for processing.

    • Added for the withdrawal_pending .

    hashtag
    2023-03-03

    hashtag
    Added

    • idempotencyKey to createPayment input.

    • idempotencyKey to createWithdrawal input.

    hashtag
    2023-02-23

    hashtag
    Added

    • Fixed the withdrawal_reviewing . It was never sent before even though declared on the Flash Connect website.

    • Added for the withdrawal_reviewing .

    hashtag
    2023-02-08

    hashtag
    Removed (BREAKING)

    • Removed the auto-creation of id for embedded senders and recipients. This means that if you (or FlashFX system) have created withdrawals and payments without explicitly providing sender or recipient ID then from now on the sender.id or recipient.id will be null. But, if you create payments or withdrawals via this API then you will always have payment.sender.id or withdrwal.recipient.id.

    hashtag
    2022-09-06

    hashtag
    Added

    • Missing expireAt property to the Quote object returned by the quote query.

    hashtag
    2022-09-02

    hashtag
    Added

    • New REVIEWING status to deposit and withdrawal status enum.

      • REVIEWING : deposit/withdrawal is being internally checked by our compliance team before proceeding.

    hashtag
    2022-08-25

    hashtag
    Added

    • New event type: deposit_initiated to notify that we received a deposit but not yet cleared it.

      • Previously only the deposit_cleared was sent and customers had no idea we are holding (reviewing) the deposit.

    hashtag
    2022-07-01

    hashtag
    Added

    • New item in deposit and related webhooks:

      • recipient - deposit recipient information as specified by deposit sender for this transaction:

    hashtag
    2022-04-22

    hashtag
    Changes

    • Additional validation for dob field introduced for Senders, Recipients and Sub-clients to enforce the data is entered in YYYY-MM-DD format. The field will also allow for only the data after 1900-01-01 and individuals of 18 years of age or older.

    hashtag
    2022-04-12

    hashtag
    Changes

    • Added validation of address fields. From now on, any address submitted as a part of any transaction should only include ASCII characters.

    hashtag
    2022-02-25

    hashtag
    Changes

    • Added deposit.sender.accountName so that you can query who deposited money to your Virtual Account Number (VAN).

    hashtag
    2022-02-14

    hashtag
    Changes

    • Additional validation for lastName, middleName and firstName introduced allowing only for latin alphabetical characters and special symbols:

    hashtag
    2022-02-09

    hashtag
    Changes

    • FundingAccount type has been extended to include all deposit details you need to bring money to Australia. Your account address can now be retrieved using accountAddress property along with name and address fields which identify the accepting financial institution associated with your account.

    hashtag
    2022-01-12

    hashtag
    Changes

    • lastName and firstName fields of Sender and Recipient objects can now be one symbol long to allow for initials. Please note that such single symbols have to be alphabetic.

    hashtag
    2021-11-02

    hashtag
    Changes

    • Occasionally Payment objects do not have sender or recipient properties. Thus these properties are now marked at "not required" (exclamation mark was removed) when querying payments.

    • We have added rate limiting. You can receive HTTP 429 error code and get temporary blocked if abusing the API too much.

    hashtag
    2021-08-13

    hashtag
    Changed (BREAKING)

    • Removed XRP currency form the list of supported currencies.

    hashtag
    2021-07-22

    hashtag
    Changed (BREAKING)

    • While creating sub-clients the address of the person/company was not required. It was a bug which was fixed. To create a sub-client you would also need their: street address, suburb/city, state/region, postcode, and country.

    hashtag
    2021-07-14

    hashtag
    Changes

    • Allow accountNo to be 4 digits long. Some old Japanese bank accounts could be just 4 digits.

    hashtag
    2021-07-08

    hashtag
    Added

    • The ability to query deposits, withdrawals, payments by the associated sub-client (subClientId).

    • The payments can also have sub-clients now. Added the Payment.subClient field.

    hashtag
    2021-06-29

    hashtag
    Added

    • The totalFee property to both Deposit and Withdrawal types as well as webhook payloads.

    hashtag
    2021-06-22

    hashtag
    Added

    • The bankInfo reference query. You can now validate your BSB for existence, check if we support your BIC, and retrieve BIC (aka SWIFT code) by IBAN.

    hashtag
    2021-06-17

    hashtag
    Added

    • The fundingAccounts and SubClient.fundingAccounts queries. It returns international bank account numbers you can deposit in order to bring money to Australia. See for more details.

    hashtag
    2021-05-25

    hashtag
    Changed

    • The senderId was always required when creating withdrawals via createWithdrawal. But now, if you provided the subClientId and didn't provide the senderId the sub-client becomes the sender, and will be reported to the government as the sender. However, you still must provide the senderId if your sub-client moves funds for other people/companies.

    hashtag
    2021-05-17

    hashtag
    Changed (BREAKING)

    • Replaced docIssuer, docType and docNumber fields from CreateSubClientInput with idDoc nested field instead.

    hashtag
    2021-04-26

    hashtag
    Changed

    • RecipientAccountIdType was fully duplicating the AccountIdType. Replace the former with the latter. This might break your auto-generated code in strongly typed languages. But won't change any API queries or responses. So, this change is not considered to be a breaking.

    hashtag
    2021-04-16

    hashtag
    Added

    • Added ability to disable and activate sub-clients

      • mutation disableSubClient(id: ID!): MutateSubClientReply

      • mutation activateSubClient(id: ID!): MutateSubClientReply

    hashtag
    2021-04-12

    hashtag
    Added

    • Added deposit queries

      • query deposits(input: DepositQueryInput): [Deposit]

      • query deposit(id: ID!): Deposit

    hashtag
    2021-01-07

    hashtag
    Removed (BREAKING)

    These types and fields were never used by anyone for couple of years.

    • Removed enum DepositMechanism.

    • PaymentInput and ConfirmPaymentInput fields:

    hashtag
    2020-12-16

    hashtag
    Added

    • New item in BsbDepositDetails

      • accountName - Australian account name.

    • New item in Withdrawal

    hashtag
    2020-10-14

    hashtag
    Added

    • New items in both query type and mutation input Senders.

      • legalName

      • tradingAsName

    hashtag
    2020-06-18

    hashtag
    Changed (BREAKING)

    • Fixed typo in RecipientQueryInput field name. snaps -> cnaps

    hashtag
    2020-05-04

    hashtag
    Added

    • New compliance-related fields to the CreateWithdrawalInput input:

      • acceptingMoneyInstitutionSenderId - you must pre-create this Sender and submit every time if you are not the FI who collected the money for this withdrawal.

    hashtag
    2020-03-05

    hashtag
    Changed (BREAKING)

    • Fixed typo in the WithdrawalStatus enum item. INITIALISING -> INITIALISED

    hashtag
    2020-02-12

    hashtag
    Added

    • callbackUri to Payment, Withdrawal, CreateWithdrawalInput. Now you can query the callback/webhook URI you have supplied earlier. Also, this allows you to receive webhooks when you create a withdrawal (aka local payout).

    hashtag
    2020-02-11

    hashtag
    Added

    • New items in RecipientQueryInput. This means that recipients can be searched by:

      • firstName

      • lastName

    hashtag
    2020-01-28

    hashtag
    Added

    • Introduced Withdrawals - send money from your account (FlashFX digital wallet) to local banks.

      • query withdrawal(id: ID): Withdrawal

      • query withdrawals(input: WithdrawalQueryInput): [Withdrawal]

    hashtag
    Removed (BREAKING)

    • Removed the unused enum PaymentType. It has no sense and was deprecated a year ago.

      • Simultaneously removed properties Payment.paymentType, PaymentQueryInput.paymentTypes, PaymentInput.paymentType.

    ,
    ams_completed
    ,
    ams_failed
    .
    ,
    CLABE
    ,
    IFSC
    ,
    CNAPS
    ,
    SORT_CODE
    , or
    ACC_NO
    , the
    bic
    field is still
    required
    .

    refundedAt - the timestamp when it was refunded. Very rare situation.

    New property for the Quote type: applicability. It indicates if the quote can be used for payments or conversions.

    New sub-client status - UNAPPROVED.
    Added corresponding webhook event types: deposit_reviewing and withdrawal_reviewing.
    The deposit_cleared will be sent immediately as we approve (clear) the deposits. So, no changes here.
    accountName
  • accountNo

  • bsb

  • New item in deposit.sender:

    • bankName

  • New mutation to refund deposits:

    • refundDeposit(id:ID! input:RefundDepositInput): RefundDepositReply

  • Introduced sub-client feature – transactional virtual account numbers for AUD processing in Australia.

    • query subClients(input: SubClientQueryInput): [SubClient]

    • query subClient(id: ID!): SubClient

    • mutation createSubClient(input: CreateSubClientInput!): MutateSubClientReply

  • Deposit and withdrawal webhooks now include subClient object with sub-client information when present

  • removed depositMechanism
  • removed depositReference

  • removed depositAmount

    • statusMessage - a human readable message of the current status reason, like processing error messages.

  • New item in Payment and PaymentInput

    • sourceOfFunds - mandatory field for some destinations.

  • New enum SourceOfFunds.

  • businessNumber - differs by country, e.g. ABN in Australia.

  • acn - Australian Company Number. Should not be used for other countries.

  • acceptingInstructionInstitutionSenderId - you must pre-create this Sender and submit every time if you were instructed by other FI to make this withdrawal.
  • middleName

  • dob - date of birth

  • companyName

  • phCashoutNetwork

  • payid

  • bic

  • iban

  • aba

  • bsb

  • clabe

  • cnaps

  • sortCode

  • ifsc

  • accountNo

  • rippleAddress

  • externalId - ID in your system

  • mutation createWithdrawal(input: CreateWithdrawalInput!): CreateWithdrawalReply

  • PHP currency support.

  • middleName property in recipients and senders.

  • PAYID recipient type for Australian local payments or withdrawals.

    • Recipient.payid new property.

  • PH_CASH recipient type for Philippines cash network payments.

    • Recipient.phCashoutNetwork new property.

  • You can now query your recipients by accountIdType property. For example: recipients(input: {`` ``accountIdType: PH_CASH`` ``})

  • Removed the long deprecated PaymentInput.recipient object. The only way to provide a recipient for a payment is via PaymentInput.recipientId. You would need to pre-create the recipient beforehand.

  • Removed the never used AccountIdType enum values: BPAY, FIN_BTN, INTERAC.

  • const bodyJSON = {
      variables: {
        input: {
          amount: 1000, 
          recipient: {                  // <- this is new !!!
            bsb: "370370",
            accountNo: "123123123",
            companyName: "Acme Pty Ltd",
            currency: "AUD",
            accountIdType: "BSB",
            address: { street: "1 Main St SYDNEY NSW 2000", country: "AU" },
          },
          sender: {                     // <- this is new too !!!
            companyName: "Acme LLC",
            address: { street: "1 Jon St PORTLAND VA 54321", country: "US" },
          },
        },
      }, 
      query: ` 
    mutation ($input: CreateWithdrawalInput!) {
      createWithdrawal(input: $input) {
        success code message withdrawal { id }
      }
    }`,
    };
    
    adverseMediaSearch
    amsRequest
    amsRequests
    webhook events
    confirmationOfPayee
    updateSubClient
    webhook
    statuses
    here
    cancel
    cancel
    GraphQL playgroundarrow-up-right
    createSender
    updateSender
    createInstitution
    createSubClient
    createWithdrawal
    createPayment
    createSender
    updateSender
    createSubClient
    updateSubClient
    Conversions
    queryarrow-up-right
    static codes and standard status messagesarrow-up-right
    get cancelledarrow-up-right
    withdrawal_cancelledarrow-up-right
    updateRecipientarrow-up-right
    instructingInstitution
    statement
    Flash Connectarrow-up-right
    flash-fx.comarrow-up-right
    flash-payments.comarrow-up-right
    webhook
    examplearrow-up-right
    webhook
    webhook
    examplearrow-up-right
    webhook
    webhook
    Auto receive funds