API Fundamentals
To kickstart your integration with Breeze, please contact us here
Before diving into the endpoints, here’s how to authenticate your API request and what you can expect across all Breeze API responses — so you can handle success, failure, and edge cases consistently.
🔒 Authentication
We use Basic Authentication to authenticate API requests. Before you get started, you’ll need to obtain an API key, which is used as the username, while the password is always an empty string.
await axios.get("https://api.breeze.cash/v1/api/...", {
auth: {
username: "your-breeze-api-key",
password: "", // <- always empty
},
});import requests
response = requests.get(
"https://api.breeze.cash/v1/api/...",
auth=("your-breeze-api-key", "")
)<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.breeze.cash/v1/api/...");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "your-breeze-api-key:");
$response = curl_exec($ch);
curl_close($ch);
?>import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Base64;
public class BreezeAPI {
public static void main(String[] args) {
try {
URL url = new URL("https://api.breeze.cash/v1/api/...");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
String auth = "your-breeze-api-key:";
String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes());
connection.setRequestProperty("Authorization", "Basic " + encodedAuth);
int responseCode = connection.getResponseCode();
// Handle the response
} catch (Exception e) {
e.printStackTrace();
}
}
}You may obtain the sandbox environment API key from the sandbox merchant dashboard. Under the Developers section, click on "Generate new API Key", then copy the key and use it as your API key in requests.
Note:
Sandbox API keys have the prefix
sk_test_, while production API keys have the prefixsk_live_.
🔑 API Key Roles & Permissions
By default, an API key has full access to your account — it can call every endpoint your plan supports. You can also create scoped keys restricted to a specific role, so a key holds only the permissions it needs — for example a read-only key for reporting, or a key that can manage payment pages but cannot move money out.
Scoped API keys are rolling out per account. If roles aren't yet available on your dashboard, keys behave as full access. Contact [email protected] to enable them.
Authentication is unchanged — a scoped key is still an sk_live_ / sk_test_ secret used as the Basic Auth username (see Authentication). A role only limits what the key can do, not how you authenticate.
Assigning a role
Create an API key from Developers → API keys in the merchant dashboard and choose a role. Leaving the role unset creates a full-access key. API keys can only be created — and roles assigned — from the dashboard, not via the API.
| Role | What it can do |
|---|---|
| Full access (default) | Everything your account supports. This is a key with no role assigned. |
| Operator | Read everything, plus manage day-to-day operations: refunds, disputes, payment pages, payout pages, blocklist, products, customers, and payment links. Cannot initiate payouts (money-out), change account settings, or manage risk. |
| Developer | Read everything, plus manage webhooks. Intended for integration and automation keys. |
| Viewer | Read-only access across all resources. |
How permissions work
Each permission is a module.action pair, where the action is read (view) or write (manage) — for example payments.read, refunds.write, or payout_pages.write. A role is simply a bundle of these permissions.
Resources an API key can be scoped to:
payments (read) · refunds · payouts · disputes · blocklist · payment_pages · payout_pages · payment_links · webhooks · subscriptions · products · customers · gateway · risk · kyc · sandbox (write) · settlements (read) · reports (read) · fraud_reports (read)
Note: Account-administration areas — API keys, team, settings, security, and embedded analytics — are managed from the dashboard only and are never exposed to API keys, regardless of role.
When a key lacks a permission
If a scoped key calls an endpoint it isn't permitted to use, the request is rejected with an authorization error that names the missing permission:
{
"status": "FAILED",
"errorCode": "AUTHORIZATION_FAILED",
"errorMessage": "Missing permission(s): payouts.write"
}Assign the key a role that includes the required permission, or use a full-access key, to make the call.
✅ Success Response
Successful API requests will return an HTTP 200 status and a JSON body with a status of SUCCEEDED, along with a data object containing the result.
{
"status": "SUCCEEDED",
"data": {
"id": "page_abc123xyz",
...
}
}status: Will always beSUCCEEDEDdata: Contains the actual result object (e.g., payment page info, payment status, etc.)
Non-required fields will be omitted from the response if they are null. See the API Reference tab for more details on request and response fields.
❌ Error Response
Failed requests will return a non-2xx HTTP status code (typically 400 or 500) with an error object like:
{
"status": "FAILED",
"errorCode": "INVALID_REQUEST",
"errorMessage": "The 'amount' field is required."
}status: Will always beFAILEDerrorCode: Machine-readable error typeerrorMessage: Human-friendly explanation
🚦 Status Codes
| HTTP Status | Meaning | Typical Causes |
|---|---|---|
| 200 | Success | Request completed without issues |
| 400 | Bad Request | Unexpected error. Please check your request and integration. |
| 500 | Internal Server Error | Something went wrong on our end |
🌐 Sandbox vs. Production (livemode)
livemode)All API requests support a livemode flag that controls which environment you're targeting:
livemode=false— targets the sandbox environment (test data, no real money movement). Append as a query parameter:?livemode=falselivemode=true(default) — targets production
Sandbox API keys (prefix sk_test_) only work with livemode=false. Production keys (prefix sk_live_) only work in production. Omitting livemode defaults to production.
🛡️ Idempotency & Retry Safety
- Creating a payment page is idempotent per
clientReferenceId. If you accidentally resend the same request, you’ll receive the same payment page. - Webhooks may occasionally be retried — your webhook handler should be idempotent (e.g., check if the order is already marked as paid before updating again).
🧾 Payment Descriptor
The descriptor that appears on a customer’s bank or card statement is assembled by Breeze using the following pattern:
BREEZE*{MerchantName}*{last 4 characters of clientReferenceId}
We recommend structuring your clientReferenceId so that the dynamic, order-specific portion appears at the end. This ensures the most meaningful part of the reference (e.g. an order ID suffix) is what surfaces in the descriptor.
Updated 9 days ago
