---
openapi: 3.1.0
info:
title: Zepto API
contact:
email: support@zepto.com.au
description: Zepto allows you to make, get and manage payments using nothing but
bank accounts.
version: '1.0'
servers:
- url: https://api.sandbox.zeptopayments.com
description: Sandbox API server
- url: https://api.zeptopayments.com
description: Production API server
tags:
- name: Agreements
description: |
An Agreement is an arrangement between two parties that allows them to agree on terms for which future Payment Requests will be auto-approved.
Zepto Agreements are managed on a per Contact basis, and if a Payment Request is sent for an amount that exceeds the terms of the agreement, it will not be created.
Please refer to the [What is an Agreement](https://help.zepto.money/articles/3094575-what-is-an-agreement) article in our knowledge base for an overview.
<div class="middle-header">Direction</div>
Agreements are therefore broken up by direction:
1. **Outgoing:** Agreement sent to one of your Contacts
2. **Outgoing:** Agreement sent to another Zepto account [Deprecated]
3. **Incoming:** Agreement received from another Zepto account [Deprecated]
##Lifecycle
An Agreement can have the following statuses:
| Status | Description |
|-------|-------------|
| `proposed` | Waiting for the Agreement to be accepted or declined. |
| `accepted` | The Agreement has been accepted and is active. |
| `cancelled` | The Agreement has been cancelled (The initiator or authoriser can cancel an Agreement). |
| `declined` | The Agreement has been declined. |
| `expended` | The Agreement has been expended (Only for [single_use Unassigned Agreements](/#Zepto-API-Unassigned-Agreements)). |
- name: Bank Accounts
description: 'Your currently linked up bank accounts.
'
- name: Contacts
description: |
Your Contacts form an address book of parties with whom you can interact. In order to initiate any type of transaction you must first have the party in your Contact list.
<aside class="notice">In the case of Open Agreements, the authorising party will be automatically added to your Contacts list.</aside>
- name: Bank Connections
description: |
Bank connections are read-only connections to your contacts' banking data. This allows Zepto (and yourself) to make intelligent transactional decisions leading to better outcomes.
Use these endpoints to:
* List your bank connections and check their status
* Retrieve a link that you can share with your contact to update their invalidated bank connection (e.g Their online banking credentials have changed)
<aside class="notice">To access these endpoints on behalf of another account via OAuth2, your application must request (and the user must authorise) <a href="#configuration">the bank_connections scope</a>.</aside>
<aside class="notice">Looking to add a new bank connection to a contact? See the <a href="#get-a-contact">get a contact endpoint</a></aside>
- name: Payments
description: |
A Payment is used to disburse funds to your Contacts.
Supported payment rails:
* **NPP**: New Payments Platform (Real-time)
* **DE / BECS**: Direct Entry / Bulk Electronic Clearing System (Slower)
##Lifecycle
> Example payout reversal response
```json
{
"data": [
{
"ref": "C.3",
"parent_ref": "PB.1",
"type": "credit",
"category": "payout_reversal",
"created_at": "2021-04-07T23:15:00Z",
"matures_at": "2021-04-07T23:15:00Z",
"cleared_at": null,
"bank_ref": null,
"status": "maturing",
"status_changed_at": "2016-12-08T23:15:00Z",
"party_contact_id": "26297f44-c5e1-40a1-9864-3e0b0754c32a",
"party_name": "Sanford-Rees",
"party_nickname": "sanford-rees-8",
"description": "Payout reversal of D.1 for Sanford-Rees due to no account or incorrect account number"
"amount": 1,
"reversal_details": {
"source_debit_ref": "D.1",
"source_credit_failure": {
"code": "E105",
"title": "Account Not Found",
"detail": "The target account number is incorrect."
}
}
}
]
}
```
A Payment is simply a group of Payouts, therefore it does not have a particular status. Its Payouts however have their status regularly updated. For a list of possible Payout statuses check out the [Transactions](/#Zepto-API-Transactions).
<aside class="notice">
Zepto no longer supports multiple Payouts within a single Payment request. A Payment request must only contain 1 Payout object.
</aside>
### Payout Reversal
When Zepto is unable to credit funds to a recipient, we will automatically create a payout reversal credit back to the payer. Furthermore, within the payout reversal credit, Zepto will include details in the `description` and under the `reversal_details` key as to why the original credit to the recipient failed.
- name: Payouts
description: |
This endpoint gives you some control over a transaction:
* After it has been created; and
* Before it has been submitted to the banks.
<aside class="notice">
Payments and Payment Requests are made up of individual Debits and Credits. These debits and credits
were once referred to as Payouts [Legacy naming].
</aside>
- name: Payment Requests
description: |
A Payment Request (PR) is used to collect funds, via direct debit, from one of your Contacts (as long as there is an accepted Agreement in place).
<div class="middle-header">Applicable scenarios</div>
1. **You send a Payment Request to a [Contact](/#Zepto-API-Contacts) in order to collect funds:**
1. Given there is an Agreement in place and the Payment Request is within the terms of the Agreement, then it will be automatically approved; **or**
1. Given the Payment Request is **not** within the terms of the Agreement, then it will not be created; **or**
1. There is no Agreement in place, then it will not be created.
1. **Your customer sends funds to you as a [Receivable Contact](/#add-a-receivable-contact):**
1. A *receivable* Payment Request will be automatically created and approved to identify the movement of funds from your customer to your chosen Zepto float account.
##Lifecycle
<aside class="notice">Payment Requests generated from a customer sending you funds will always be <code>approved</code></aside>
A Payment Request can have the following statuses:
| Status | Description |
|-------|-------------|
| `approved` | The debtor has approved the Payment Request. |
| `cancelled` | The creditor has cancelled the Payment Request. |
<div class="middle-header">Prechecking</div>
When using Payment Requests to collect payments from your customer, Zepto will automatically check for available funds before **attempting to debit** the debtor. This check is only performed for contacts with an active [bank connection](/#Zepto-API-Bank-Connections).
- name: Refunds
description: |2
Refunds can be issued for any successfully completed Payment Request transaction. This includes:
1. Payment Requests for direct debit payments **(Collections)**:
2. Payment Requests for funds received via DE/NPP **(Receivables)**:
This allows you to return any funds that were previously collected or received into one of your bank/float accounts.
- name: Transactions
description: |
By default, the transactions endpoint provides a detailed look at all past, current and future debits & credits related to your account.
<aside class="notice">Want to also know about the debits & credits applied to the other party? No problem! Use the <code>both_parties=true</code> query string.</aside>
##Lifecycle
A transaction (debit or credit) can have the following statuses:
| Status | Description |
|--------|-------------|
| `maturing` | The maturation date has not yet been reached. |
| `matured` | The maturation date has been reached and the transaction is eligible for processing. |
| `preprocessing` | The transaction is undergoing pre-checks before being sent to the bank. |
| `processing` | The transaction has been submitted to the bank. |
| `clearing` | Waiting for confirmation from the bank that the transaction has succeeded. |
| `cleared` | The transaction is complete. |
| `rejected` | The bank has rejected the transaction due to incorrect bank account details. |
| `returned` | The transaction did not successfully clear. |
| `voided` | The transaction has been cancelled and is no longer eligible for processing. |
| `pending_verification` | The bank account must be verified before the transaction can proceed. |
| `paused` | The transaction has temporary been paused by Zepto pending internal review. |
| `channel_switched` | The initial payment channel has failed and the credit has automatically switched to attempt the payment using the next available channel. |
## Failure codes
> Example response
```json
{
"data": [
{
"ref": "D.3",
"parent_ref": null,
"type": "debit",
"category": "payout_refund",
"created_at": "2021-04-07T23:15:00Z",
"matures_at": "2021-04-10T23:15:00Z",
"cleared_at": null,
"bank_ref": null,
"status": "returned",
"status_changed_at": "2021-04-08T23:15:00Z",
"failure" : {
"code": "E251",
"title": "Voided By Initiator",
"detail": "The transaction was voided by its initiator.",
},
"failure_details": "Wrong amount - approved by Stacey"
"party_contact_id": "26297f44-c5e1-40a1-9864-3e0b0754c32a",
"party_name": "Sanford-Rees",
"party_nickname": "sanford-rees-8",
"description": null,
"amount": 1,
"bank_account_id": "56df206a-aaff-471a-b075-11882bc8906a"
"channels": ["float_account"]
"current_channel": "float_account"
}
]
}
```
The rejected, returned & voided statuses are always accompanied by a failure code, title and detail as listed below.
### DE credit failures
| Code | Title | Detail |
| ------------ | ------------- | -------------- |
| E101 | Invalid BSB Number | The BSB is not valid or is no longer active. |
| E102 | Payment Stopped | The target institution has blocked transactions to this account. Please refer to customer. |
| E103 | Account Closed | The target account is closed. |
| E104 | Customer Deceased | The target account's owner has been listed as deceased. |
| E105 | Account Not Found | The target account number cannot be found by the financial institution. |
| E106 | Refer to Customer | Usually means that there is an issue with the account receiving a credit that only the customer and their financial institution can resolve. Please refer to customer. |
| E107 | Account Deleted | The target account is deleted. |
| E108 | Invalid UserID | Please contact Zepto for further information. |
| E109 | Technically Invalid | Usually means that the account is not creditable or that the reason for failure cannot be categorised within the standard BECS return codes. Please refer to customer. |
| E150 | Voided By Admin | The transaction was voided by an administrator. |
| E151 | Voided By Initiator | The transaction was voided by its initiator. |
| E152 | Insufficient Funds | There were insufficient funds to complete the transaction. |
| E153 | System Error | The transaction was unable to complete. Please contact Zepto for assistance. |
| E154 | Account Blocked | The target account is blocked and cannot receive funds. |
| E199 | Unknown DE Error | An unknown DE error occurred. Please contact Zepto for assistance. |
### DE debit failures
| Code | Title | Detail |
| ------------ | ------------- | -------------- |
| E201 | Invalid BSB Number | The BSB is not valid or is no longer active. |
| E202 | Payment Stopped | The target institution has blocked transactions to this account. Please refer to customer. |
| E203 | Account Closed | The target account is closed. |
| E204 | Customer Deceased | The target account's owner has been listed as deceased. |
| E205 | Account Not Found | The target account number cannot be found by the financial institution. |
| E206 | Refer to Customer | Usually means insufficient funds or that the target account has breached their transaction limits. |
| E207 | Account Deleted | The target account is deleted. |
| E208 | Invalid UserID | Please contact Zepto for further information. |
| E209 | Technically Invalid | Usually means that the account is not debitable or that the reason for failure can not be categorised within the standard BECS return codes. Please refer to customer. |
| E250 | Voided By Admin | The transaction was voided by an administrator. |
| E251 | Voided By Initiator | The transaction was voided by its initiator. |
| E252 | Insufficient Funds | There were insufficient funds to complete the transaction. |
| E253 | System Error | The transaction was unable to complete. Please contact Zepto for assistance. |
| E299 | Unknown DE Error | An unknown DE error occurred. Please contact Zepto for assistance. |
### NPP credit failures
| Code | Title | Detail |
| ------------ | ------------- | -------------- |
| E301 | Upstream Network Outage | An upstream network issue occurred. Please try again later. |
| E302 | BSB Not NPP Enabled | The target BSB is not NPP enabled. Please try another channel. |
| E303 | Account Not NPP Enabled | The target account exists but cannot accept funds via the NPP. Please try another channel. |
| E304 | Account Not Found | The target account number cannot be found. |
| E305 | Intermittent Outage At Target Institution | The target financial institution is experiencing technical difficulties. Please try again later. |
| E306 | Account Closed | The target account is closed. |
| E307 | Target Institution Offline | The target financial institution is undergoing maintenance or experiencing an outage. Please try again later. |
| E308 | Account Blocked | The target account is blocked and cannot receive funds. |
| E399 | Unknown NPP Error | An unknown NPP error occurred. Please contact Zepto for assistance. |
- name: Transfers
description: |2
This endpoint lets you Transfer funds between any bank & float accounts registered under your Zepto account:
1. **From**: Bank Account **To**: Float Account:
* Topping up a float account via Direct Debit
* Up to 2 days
2. **From**: Float Account **To**: Bank Account:
* Withdrawing from a float account
* Will attempt NPP first and channel switch to DE if required
3. **From**: Float Account **To**: Float Account:
* Transfer between two float accounts
* Within seconds
- name: Unassigned Agreements
description: |
An agreement with no preset authoriser that can only be accepted once and must be accepted within a predefined time period.
Unassigned Agreements are shared using the generated link available in the response body. You can then include it in an email, text message, embed it in an iFrame, etc...
Please refer to the [Unassigned Agreement](https://help.zepto.money/agreements/unassigned-agreement) article in our knowledge base for more information.
- name: Ping
description: Test your connectivity and authentication.
- name: Users
description: 'All about the currently authenticated user.
'
- name: Sandbox Only
description: Special testing endpoints that only exist in the sandbox environment.
paths:
"/agreements/outgoing":
get:
tags:
- Agreements
summary: List Agreements
description: By default, all outgoing Agreements will be returned. You can apply
filters to your query to customise the returned Agreements.
operationId: ListOutgoingAgreements
parameters:
- name: page
in: query
description: Page of results to return, single value, exact match
style: form
schema:
type: string
example: '1'
- name: per_page
in: query
description: Number of results per page, single value, exact match
style: form
schema:
type: string
example: '100'
- name: authoriser_id
in: query
description: Authoriser ID (`Contact.data.account.id`), single value, exact
match
style: form
schema:
type: string
example: 2c4dec90-8a4c-4685-b620-bd1d7ca05a60
- name: contact_id
in: query
description: Contact ID (`Contact.data.id`), single value, exact match
style: form
schema:
type: string
example: e5edc264-1771-4809-9cf5-b40baaee15f7
- name: status
in: query
description: Exact match
style: form
explode: false
schema:
type: array
items:
type: string
enum:
- proposed
- accepted
- declined
- cancelled
example:
- proposed
responses:
'200':
description: OK
headers:
Link:
"$ref": "#/components/headers/Link"
Per-Page:
"$ref": "#/components/headers/Per-Page"
content:
application/json:
schema:
"$ref": "#/components/schemas/ListOutgoingAgreementsResponse"
parameters:
- "$ref": "#/components/parameters/ZeptoAPIVersion"
"/agreements/{agreement_ref}":
get:
tags:
- Agreements
summary: Get an Agreement
description: Get a single Agreement by its reference
operationId: GetAgreement
parameters:
- name: agreement_ref
in: path
description: Single value, exact match
required: true
style: simple
schema:
type: string
pattern: "^[ -~]+$"
example: A.2
responses:
'200':
description: OK
content:
application/json:
schema:
"$ref": "#/components/schemas/GetAgreementResponse"
delete:
tags:
- Agreements
summary: Cancel an Agreement
description: An Agreement can be cancelled by the initiator at any time whilst
the authoriser (Agreement recipient) can only cancel a previously accepted
Agreement.
operationId: CancelAgreement
parameters:
- name: agreement_ref
in: path
description: Single value, exact match.
required: true
style: simple
schema:
type: string
pattern: "^[ -~]+$"
example: A.2
responses:
'204':
description: No Content
parameters:
- "$ref": "#/components/parameters/ZeptoAPIVersion"
"/bank_accounts":
get:
tags:
- Bank Accounts
summary: List all Bank Accounts
description: 'By default, all Bank Accounts will be returned.
'
operationId: ListAllBankAccounts
responses:
'200':
description: OK
headers:
Link:
"$ref": "#/components/headers/Link"
Per-Page:
"$ref": "#/components/headers/Per-Page"
content:
application/json:
schema:
"$ref": "#/components/schemas/ListAllBankAccountsResponse"
parameters:
- "$ref": "#/components/parameters/ZeptoAPIVersion"
"/bank_accounts/{id}":
get:
tags:
- Bank Accounts
summary: Get a Bank Account
description: Returns a specified Bank or Float Account owned by your account.
For a Float Account, the response includes its current `available_balance`.
operationId: GetABankAccount
parameters:
- name: id
in: path
description: Bank Account ID (`BankAccount.data.id`), single value, exact
match
required: true
style: simple
schema:
type: string
format: uuid
example: ab3de19b-709b-4a41-82a5-3b43b3dc58c9
responses:
'200':
description: OK
content:
application/json:
schema:
"$ref": "#/components/schemas/GetABankAccountResponse"
'403':
description: Forbidden - the access token does not have the `bank_accounts`
scope
'404':
description: Not Found - the Bank Account is unavailable or is not owned
by the authenticated account
parameters:
- "$ref": "#/components/parameters/ZeptoAPIVersion"
"/bank_accounts/{bank_account_id}/entries":
get:
tags:
- Bank Accounts
summary: List Float Account entries
description: |-
Lists the settled ledger entries applied to a Float Account. Transactions and Transfers describe business operations; entries describe what was posted to this Float Account and changed its available balance. An entry may result from a payment, transfer, refund, recovery, return, fee, or manual adjustment, making this endpoint the complete account-level record within the availability window for reconciliation.
Float Account entries are available through this API for a rolling 24-month period, calculated from the time of the request. Entries created before the start of that window are not returned. Requests with either created-at filter before the start of the window return `422 Unprocessable Entity`.
Entries are returned in descending order by `created_at` and then `id`. The ID is a deterministic tie-breaker; entries with the same timestamp are not guaranteed to be returned in their original balance-application order.
`amount` is expressed in cents. Positive values credit the Float Account and negative values debit it.
operationId: ListFloatAccountEntries
parameters:
- name: bank_account_id
in: path
description: Bank Account ID (`BankAccount.data.id`), single value, exact
match
required: true
style: simple
schema:
type: string
format: uuid
example: ab3de19b-709b-4a41-82a5-3b43b3dc58c9
- name: min_created_date
in: query
description: Filter by minimum `created_at`. The value must not be earlier
than the start of the rolling 24-month availability window. Date/time UTC
ISO 8601 format, single value, exact match.
required: false
schema:
type: string
format: date-time
example: '2026-07-01T00:00:00Z'
- name: max_created_date
in: query
description: Filter by maximum `created_at`. The value must not be earlier
than the start of the rolling 24-month availability window. Date/time UTC
ISO 8601 format, single value, exact match.
required: false
schema:
type: string
format: date-time
example: '2026-07-31T23:59:59Z'
- name: per_page
in: query
description: Number of entries to return. Defaults to 20 and is constrained
to 1–100.
required: false
schema:
type: integer
minimum: 1
maximum: 100
default: 20
example: 20
- name: starting_after
in: query
description: ID of the final entry from the previous page. Return the value
from the `Link` header unchanged.
required: false
schema:
type: string
format: uuid
example: '019c8814-c767-753c-82f7-3daac44d8662'
responses:
'200':
description: OK
headers:
Link:
schema:
type: string
description: Contains the next-page URL when another page exists
example: </bank_accounts/ab3de19b-709b-4a41-82a5-3b43b3dc58c9/entries?per_page=20&starting_after=019c8814-c767-753c-82f7-3daac44d8662>;
rel="next"
Per-Page:
schema:
type: integer
description: Contains the maximum number of entries requested for this
page. Defaults to 20.
example: 20
content:
application/json:
schema:
"$ref": "#/components/schemas/ListFloatAccountEntriesResponse"
'400':
description: Bad Request - `per_page` is not an integer
'403':
description: Forbidden - the access token does not have the `bank_accounts`
scope
'404':
description: Not Found - the Bank Account is unavailable or is not a Float
Account
'422':
description: Unprocessable Entity - `starting_after` is not an available
entry in this Float Account, or a `created_at` filter is invalid or outside
the rolling 24-month availability window
content:
application/json:
schema:
type: object
required:
- errors
properties:
errors:
type: array
items:
type: object
required:
- title
- detail
properties:
title:
type: string
detail:
type: string
examples:
Minimum created date outside availability window:
value:
errors:
- title: Validation Failed
detail: min_created_date must not be earlier than the start
of the 24-month availability window
Maximum created date outside availability window:
value:
errors:
- title: Validation Failed
detail: max_created_date must not be earlier than the start
of the 24-month availability window
parameters:
- "$ref": "#/components/parameters/ZeptoAPIVersion"
"/bank_accounts/{bank_account_id}/entries/{entry_id}":
get:
tags:
- Bank Accounts
summary: Get a Float Account entry
description: |-
Gets one settled entry applied to a Float Account.
Float Account entries are available through this API for a rolling 24-month period, calculated from the time of the request.
operationId: GetFloatAccountEntry
parameters:
- name: bank_account_id
in: path
description: Bank Account ID (`BankAccount.data.id`), single value, exact
match
required: true
style: simple
schema:
type: string
format: uuid
example: ab3de19b-709b-4a41-82a5-3b43b3dc58c9
- name: entry_id
in: path
description: Float Account entry ID (`FloatAccountEntry.data.id`), single
value, exact match
required: true
style: simple
schema:
type: string
format: uuid
example: '019c8814-c767-753c-82f7-3daac44d8662'
responses:
'200':
description: OK
content:
application/json:
schema:
"$ref": "#/components/schemas/GetFloatAccountEntryResponse"
'403':
description: Forbidden - the access token does not have the `bank_accounts`
scope
'404':
description: Not Found - the Bank Account or entry is unavailable, the entry
is outside the rolling 24-month availability window, or the Bank Account
is not a Float Account
parameters:
- "$ref": "#/components/parameters/ZeptoAPIVersion"
"/contacts/anyone":
post:
tags:
- Contacts
summary: Add a Contact
description: |
Use this endpoint when you want to pay somebody.
<aside class="notice">
A Contact added this way cannot be debited.
</aside>
operationId: AddAnAnyoneContact
parameters: []
requestBody:
description: ''
content:
application/json:
schema:
"$ref": "#/components/schemas/AddAnAnyoneContactRequest"
required: true
responses:
'201':
description: Created
content:
application/json:
schema:
"$ref": "#/components/schemas/AddAnAnyoneContactResponse"
parameters:
- "$ref": "#/components/parameters/ZeptoAPIVersion"
"/contacts/receivable":
post:
tags:
- Contacts (Receivable)
summary: Add a Receivable Contact
description: |
Receive funds from a Contact by allowing them to pay to a personalised PayID or account number. Perfect for reconciling incoming funds to a customer, receiving funds instantly, eliminating human error & improving your customer's experience.
<aside class="notice">
To enable this feature, please contact our support team with the following information:
<li>Your full legal business name</li>
<li>A legally owned domain name: for your PayID email addresses</li>
<li><strong>alias_name</strong>: the business name that will be displayed to your customers upon PayID resolution. We suggest using a shortened name appropriate for mobile displays</li>
</aside>
<aside class="notice">
There are two strategies supported for PayID assignment when creating this type of Contact:
<li><strong>On-demand PayID</strong>: provide a <code>payid_email</code> and we'll create a contact and register a PayID with the given email address. The PayID registration process happens when the request is received. The initial response for <code>payid_details.state</code> will always be <code>pending</code>. It will transition to <code>active</code> when the PayID registration process is complete. This can take up to a few seconds. You can use webhooks to be informed of this state change.</li>
<li><strong>Pooled PayID</strong>: provide your <code>payid_email_domain</code> and we'll create a contact and assign them a PayID from your pool. Pooled PayIDs are pre-registered. The PayID email value is generated using a random value and the email domain from your PayID pool configuration. Providing both <code>payid_email</code> and <code>payid_email_domain</code> will ignore your pool and use the "On-demand PayID" strategy instead.</li>
</aside>
<aside class="notice">
While unlikely, it is possible that we will be unable to register the given PayID. In this case <code>payid_details.state</code> will transition to <code>failed</code>.
You can simulate this path in sandbox by adding <code>+failure</code> to your <code>payid_email</code> e.g <code>test+failure@zeptopayments.com</code>
</aside>
<aside class="notice">
You can test receiving payments to a Receivable Contact in our sandbox environment using the <a href="https://docs.zeptopayments.com/reference/simulateincomingpayidpayment">PayID simulation endpoint</a>.
</aside>
operationId: AddAReceivableContact
parameters: []
requestBody:
description: ''
content:
application/json:
schema:
"$ref": "#/components/schemas/AddAReceivableContactRequest"
required: true
responses:
'201':
description: Created
content:
application/json:
schema:
"$ref": "#/components/schemas/AddAReceivableContactResponse"
'404':
description: Not Found
parameters:
- "$ref": "#/components/parameters/ZeptoAPIVersion"
"/contacts/{contact_id}/receivable/disable":
post:
tags:
- Contacts (Receivable)
summary: Disable a Receivable Contact
description: |
This endpoint should be used to Disable a Receivable Contact.
This will reject all payments made to the relevant Account number or PayID and return them to your customer. Payme
# --- truncated at 32 KB (165 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/zepto-payments/refs/heads/main/openapi/zepto-payments-zepto.yml