Skip to main content

DZBuild API — Introduction

Build on DZBuild — full REST API for stores, products, orders, customers, landing pages, signups, and webhooks.

Written by Support

💡 Tip — Build your own DZBuild apps

Build apps that merchants can install on their DZBuild stores. Visit the Developer Portal at dzbuild.dev for official starters and guides, or create an app.

The Enterprise requirement below applies to personal merchant API keys. App installations follow separate access rules, including the app's minimum plan and permissions.

The DZBuild API lets you manage your store programmatically: products, orders, customers, landing pages, plus a high-volume signup tracker for merchants embedding DZBuild in their own platforms.

Base URL: https://api.dzbuild.app/v1 — the only supported public base URL. Versioning: stable v1. Breaking changes require a new path prefix. Format: JSON in, JSON out, UTF-8. Authentication: see Authentication. Personal API keys: require a store with an active Enterprise plan. This requirement does not apply to app installation tokens, which follow the access rules linked above. Status: Pilot. The owner of a store on an active Enterprise plan creates personal keys in the dashboard at Settings → API (/dashboard/api). A new key is enrolled in the pilot automatically and works at once, so there is nothing to request from support.

⚠️ Warning — Point your integration at api.dzbuild.app, nothing else

https://dzbuild.com/api/v1 is an internal alias, not an integration target. On that hostname: /v1/signups and /v1/events do not exist (404), public-key (DZ-Public) calls are rejected with 401. Idempotent replay and the per-store rate limit apply on both hosts.

Quickstart

curl https://api.dzbuild.app/v1/ping

Response:

{ "data": { "pong": true, "time": "2026-04-30T20:15:59.836Z", "edge": true },
  "meta": { "request_id": "...", "api_version": "v1", "edge": true } }

Authenticated request:

curl https://api.dzbuild.app/v1/whoami \
  -H "Authorization: Bearer <your_key_id>.<your_key_secret>"

Response:

{ "data": { "key_id": "dzpk_live_xxxxxxxxxxxxxx", "store_id": 10, "type": "platform",
            "rate_limit_tier": "enterprise", "pilot": true,
            "scopes": ["store:read", "store:write", "products:read", "products:write",
                       "orders:read", "orders:write", "customers:read", "landing_pages:read",
                       "landing_pages:write", "promos:read", "promos:write", "pixels:read",
                       "pixels:write", "shipping:read", "shipping:write", "webhooks:read",
                       "webhooks:write", "usage:read", "analytics:read", "whatsapp:read",
                       "whatsapp:send"] },
  "meta": { "request_id": "...", "api_version": "v1" } }

scopes lists what this key may call: an endpoint that needs a scope missing from the list answers 403 with Missing scope: and the scope's name. Called with an installed app's token, whoami also returns app, with its app_id, client_id and install_id.

Envelope

Every response follows the same shape:

Success

{ "data": ..., "meta": { "request_id": "...", "api_version": "v1" } }

Error

{ "error": { "code": "rate_limited", "message": "...", "retry_after": 12 },
  "meta": { "request_id": "...", "api_version": "v1" } }

Response headers

Header

When

Meaning

X-Request-Id

Every response

Same value as meta.request_id, except on an idempotent replay: its body is the stored one and keeps the first call's meta.request_id. Send your own X-Request-Id and we echo it back, so your logs and ours line up.

X-Api-Version

Most responses

Always v1.

X-Cache

GET /v1/products, GET /v1/landing-pages, GET /v1/store and its sub-paths

Always MISS: these reads are served fresh.

Idempotency-Replay

Replayed writes

1 means this is the stored response of an earlier call with the same Idempotency-Key — no new side effect happened. See Idempotency.

Good to know

  • Your key is verified on every single request — Bearer tokens and public-key HMAC signatures alike.

  • The per-minute rate limit applies per store — all of a store's keys share one budget — on a fixed 60-second window (the counter resets on each wall-clock minute). Enforcement is approximate under bursts, so handle 429 defensively rather than pacing exactly to the limit. It applies to API calls only — a merchant's storefront, checkout and dashboard never consume it. See Rate limits.

  • Every GET is served fresh from the platform: there is no edge read cache on api.dzbuild.app, so GET /v1/products, GET /v1/landing-pages, GET /v1/store and every GET under it return the current values on each call. Cache on your side when you read at scale.

  • High-volume writes (/v1/signups, /v1/events) are accepted asynchronously and return 202 Accepted immediately — your call doesn't wait for processing to finish.

Did this answer your question?