Customers are end-users who placed an order on your storefront. They're created automatically at first checkout — there is no public sign-up flow at v1. Each customer is scoped to one store: the same phone number on two different stores creates two customer rows.
Deduplication: when a new checkout arrives, we match on store + phone. If that customer already exists, their email/address/wilaya are updated and the record is reused; otherwise a new one is created. Email is not used for dedup — historically merchants get many anonymous orders without an email.
When a customer is created through POST /v1/orders, the entire customer.name string is stored in first_name and last_name is left empty — the first/last split shown in the examples below never happens for API-created records. For an existing customer matched by phone, only first_name is overwritten and any existing last_name is left untouched. Split client-side if you need it.
GET /v1/customers
List customers in your store. Cursor-paginated.
Auth: any active platform key for the store (customers:read is granted by default and is not separately enforced at v1).
Query parameters
Param | Type | Notes |
| int 1–200 | Default 50 |
| string | Opaque |
| string | Exact match, case-insensitive |
| string | Exact match, case-insensitive |
There are no date, free-text search, sort or is_banned filters at v1; results are always newest-id-first.
Request
curl 'https://api.dzbuild.app/v1/customers?limit=20' \ -H "Authorization: Bearer $DZ_KEY"
Response 200
{
"data": {
"items": [
{
"id": 5578,
"first_name": "John",
"last_name": "Doe",
"phone": "0555000000",
"email": null,
"wilaya_id": 16,
"commune": "Bab Ezzouar",
"total_orders": 3,
"total_spent": 4500,
"is_banned": false,
"created_at": "2026-03-17 15:18:13",
"updated_at": "2026-04-15 12:01:08"
}
],
"next_cursor": "NDk=",
"has_more": true
}
}
⚠️ Warning — total_orders / total_spent are stale counters, not live aggregates
They are only incremented when an order is placed from a landing page or created manually in the dashboard. They are never adjusted on a status change (a cancelled order still counts), and orders created via the storefront or POST /v1/orders never update them at all. Don't use them for revenue reporting — aggregate GET /v1/orders (or /v1/customers/{id}/orders) yourself.
GET /v1/customers/{id}
Full detail.
Auth: any active platform key for the store (customers:read is not separately enforced at v1).
Response 200
{
"data": {
"id": 5578,
"first_name": "John",
"last_name": "Doe",
"phone": "0555000000",
"email": "[email protected]",
"wilaya_id": 16,
"commune": "Bab Ezzouar",
"address": "12 Rue X",
"notes": "Prefers afternoon delivery",
"total_orders": 3,
"total_spent": 4500,
"fraud_score": 0,
"is_banned": false,
"created_at": "2026-03-17 15:18:13",
"updated_at": "2026-04-15 12:01:08"
}
}
Field | Notes |
| Merchant-private comment, set in dashboard |
| Always |
| Set when you blacklist the customer in the dashboard. Storefront and landing-page checkouts reject banned customers — but |
Device / identity signals | Not exposed via API for privacy reasons |
GET /v1/customers/{id}/orders
Customer's orders, cursor-paginated, newest first.
Auth: any active platform key for the store (customers:read is not separately enforced at v1).
The customer id is ownership-checked first, so an unknown id, or one belonging to another store, returns 404 not_found rather than an empty list.
Request
curl 'https://api.dzbuild.app/v1/customers/5578/orders?limit=10' \ -H "Authorization: Bearer $DZ_KEY"
Response 200
{
"data": {
"items": [
{ "id": 6894, "order_number": "ORD-13-20260317-AD3C91F7", "status": "confirmed",
"payment_status": "pending", "total": 1000, "created_at": "2026-03-17 15:18:13" }
],
"next_cursor": null,
"has_more": false
}
}
This is a subset of /v1/orders filtered by customer_id — fields are the same as the orders list summary. To get the full order body call /v1/orders/{id}.
Common patterns
"Find a customer by phone, then list their orders"
PHONE="0555000000"
CUST=$(curl -sS "https://api.dzbuild.app/v1/customers?phone=$PHONE&limit=1" \
-H "Authorization: Bearer $DZ_KEY" | jq -r '.data.items[0].id')[ -z "$CUST" ] && { echo "no customer"; exit 1; }curl -sS "https://api.dzbuild.app/v1/customers/$CUST/orders" \
-H "Authorization: Bearer $DZ_KEY"
"Top 10 spenders this month"
There's no native sort-by-spend filter at v1. Walk the customer list and sort client-side; the dataset is small (typical store has < 5K active customers). Or query /v1/orders?since=... and aggregate by customer_id.
Privacy notes
The API never exposes device fingerprints or any cross-store identity link.
Customer email/phone are PII — be careful about logging them.
Future right-to-erasure (RGPD-style) requests should go through dashboard / support; the API will gain a
DELETE /v1/customers/{id}endpoint in a future version with explicit cascade rules.