Discover Bills
curl --request POST \
--url https://api.oneclickdz.com/v3/bills/discover \
--header 'Content-Type: application/json' \
--header 'X-Access-Token: <api-key>' \
--data '
{
"partner": "<string>",
"account": {},
"ref": "<string>"
}
'import requests
url = "https://api.oneclickdz.com/v3/bills/discover"
payload = {
"partner": "<string>",
"account": {},
"ref": "<string>"
}
headers = {
"X-Access-Token": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-Access-Token': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({partner: '<string>', account: {}, ref: '<string>'})
};
fetch('https://api.oneclickdz.com/v3/bills/discover', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.oneclickdz.com/v3/bills/discover",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'partner' => '<string>',
'account' => [
],
'ref' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Access-Token: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.oneclickdz.com/v3/bills/discover"
payload := strings.NewReader("{\n \"partner\": \"<string>\",\n \"account\": {},\n \"ref\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Access-Token", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.oneclickdz.com/v3/bills/discover")
.header("X-Access-Token", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"partner\": \"<string>\",\n \"account\": {},\n \"ref\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.oneclickdz.com/v3/bills/discover")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Access-Token"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"partner\": \"<string>\",\n \"account\": {},\n \"ref\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"transactionId": "<string>",
"ref": "<string>",
"status": "<string>"
}
}Bill Payment
Discover Bills
Find the unpaid bills of a customer account
POST
/
v3
/
bills
/
discover
Discover Bills
curl --request POST \
--url https://api.oneclickdz.com/v3/bills/discover \
--header 'Content-Type: application/json' \
--header 'X-Access-Token: <api-key>' \
--data '
{
"partner": "<string>",
"account": {},
"ref": "<string>"
}
'import requests
url = "https://api.oneclickdz.com/v3/bills/discover"
payload = {
"partner": "<string>",
"account": {},
"ref": "<string>"
}
headers = {
"X-Access-Token": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-Access-Token': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({partner: '<string>', account: {}, ref: '<string>'})
};
fetch('https://api.oneclickdz.com/v3/bills/discover', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.oneclickdz.com/v3/bills/discover",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'partner' => '<string>',
'account' => [
],
'ref' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Access-Token: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.oneclickdz.com/v3/bills/discover"
payload := strings.NewReader("{\n \"partner\": \"<string>\",\n \"account\": {},\n \"ref\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Access-Token", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.oneclickdz.com/v3/bills/discover")
.header("X-Access-Token", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"partner\": \"<string>\",\n \"account\": {},\n \"ref\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.oneclickdz.com/v3/bills/discover")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Access-Token"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"partner\": \"<string>\",\n \"account\": {},\n \"ref\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"transactionId": "<string>",
"ref": "<string>",
"status": "<string>"
}
}Starts a discovery and returns a
transactionId immediately. The bills arrive on the transaction a few seconds later: poll Get Transaction by ID until status is READY.
Request body
string
required
One of
ADE, SONELGAZ, SEAAL, AADL, SEOR, Algérie Télécom (exact spelling, with accents).object
required
Exactly one identifier, in the shape the partner expects:
Full rules and examples: Partners and accounts.
| Partner | account |
|---|---|
ADE | { "electronic_payment_key": string } — 25 characters |
SONELGAZ | { "sonelgaz": { "invoice_number": string, "amount_without_stamp": string, "ebb_key": string } } |
SEAAL | { "seaal": { "code_client": string, "code_contrat": string } } — 2–6 alphanumeric, 2–10 digits |
AADL | { "aadl": { "codeloc": string } } — 6–20 digits |
SEOR | { "seor": { "contrat": string, "facture": string } } — 1–6 digits (spaces ignored), 18 letters or digits |
Algérie Télécom | { "phone_number": string } — landline, 0[2-4] then 7 digits |
string
required
Your reference for this discovery, up to 100 characters. Must be unique among your transactions for this partner; a reused value is refused with
403 DUPLICATED_REF. The transaction keeps this ref and Get Transaction by Reference resolves it.Response
object
required
Example
curl -X POST https://api.oneclickdz.com/v3/bills/discover \
-H "X-Access-Token: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"partner": "SEAAL",
"account": { "seaal": { "code_client": "100001", "code_contrat": "446563" } },
"ref": "disc-20260920-0003"
}'
const response = await fetch("https://api.oneclickdz.com/v3/bills/discover", {
method: "POST",
headers: {
"X-Access-Token": process.env.ONECLICKDZ_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
partner: "SEAAL",
account: { seaal: { code_client: "100001", code_contrat: "446563" } },
ref: "disc-20260920-0003",
}),
});
const body = await response.json();
if (!body.success) throw new Error(`${body.error.code}: ${body.error.message}`);
const { transactionId } = body.data;
import os, requests
response = requests.post(
"https://api.oneclickdz.com/v3/bills/discover",
headers={"X-Access-Token": os.environ["ONECLICKDZ_API_KEY"]},
json={
"partner": "SEAAL",
"account": {"seaal": {"code_client": "100001", "code_contrat": "446563"}},
"ref": "disc-20260920-0003",
},
)
body = response.json()
if not body["success"]:
raise RuntimeError(f'{body["error"]["code"]}: {body["error"]["message"]}')
transaction_id = body["data"]["transactionId"]
<?php
$ch = curl_init("https://api.oneclickdz.com/v3/bills/discover");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
"X-Access-Token: " . getenv("ONECLICKDZ_API_KEY"),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"partner" => "SEAAL",
"account" => ["seaal" => ["code_client" => "100001", "code_contrat" => "446563"]],
"ref" => "disc-20260920-0003",
]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);
if (!$body["success"]) {
throw new Exception($body["error"]["code"] . ": " . $body["error"]["message"]);
}
$transactionId = $body["data"]["transactionId"];
?>
Response
{
"success": true,
"data": {
"transactionId": "68cdf0a2b7c1e4d5f6a7b8c9",
"ref": "disc-20260920-0003",
"status": "PENDING"
},
"meta": { "timestamp": "2026-09-20T10:15:32.194Z" },
"requestId": "req_9f3a1c72e0b84d51aB3xZq07"
}
Errors
Returned immediately; no transaction is created.| HTTP | Code | Meaning |
|---|---|---|
| 400 | ERR_VALIDATION | Bad partner, account or ref; details lists each problem |
| 400 | INVALID_ACCOUNT | Sandbox only: the invalid-account test accounts answer immediately. In production a rejected identifier surfaces on the transaction |
| 401 | MISSING_ACCESS_TOKEN / INVALID_ACCESS_TOKEN | Missing or rejected key |
| 403 | DUPLICATED_REF | ref already in use for this partner |
| 409 | BILL_ALREADY_PAID | A payment for this account or bill already succeeded through this API |
| 409 | PAYMENT_IN_PROGRESS | A payment for this account is currently running |
| 503 | PARTNER_UNAVAILABLE | The biller is unavailable or switched off |
| 503 | AUTH_UNAVAILABLE | The key could not be verified in time; retry after Retry-After |
Outcome of the discovery
Read it from the transaction:status | Meaning |
|---|---|
READY | bills[] lists the unpaid bills; an empty array means nothing is due |
FAILED | error.code is INVALID_ACCOUNT, BILL_ALREADY_PAID, PARTNER_UNAVAILABLE or, for any other rejection by the biller’s portal, PAYMENT_DECLINED |

