Developers

Dropzon Public API

Integrate DZ Address lookup, Dropzon location search, package tracking, “Sign in with Dropzon” OAuth, and more into your applications. Built for e-commerce platforms, logistics companies, and developers.

Version:v1Stable

Quick Start

1

Get your API key

Sign in to the Developer Console and create an API key. Any Dropzon account can access the console.

2

Authenticate your requests

Include your API key in every request header.

curl -H "Authorization: Bearer YOUR_API_KEY" \
     "https://api.dropzon.app/api/v1/addresses/lookup?code=DZ%23001-01"
3

Start building

Explore the endpoints below. All responses are JSON. Rate limit: 100 requests/minute per key.

Authentication

All API requests require authentication using a Bearer token in the Authorization header.

Authorization: Bearer YOUR_API_KEY

Rate Limit

100 requests / minute

Per API key. Burst-friendly with sliding window.

Response Format

JSON (application/json)

All responses include a success boolean.

Error Handling

Errors follow a consistent format with HTTP status codes and descriptive messages.

{
  "success": false,
  "error": "Invalid or expired API key",
  "code": "AUTH_INVALID"
}
StatusCodeDescription
400BAD_REQUESTMissing or invalid parameters
401AUTH_INVALIDInvalid or missing API key
403FORBIDDENInsufficient permissions for this resource
404NOT_FOUNDResource not found
429RATE_LIMITEDToo many requests - slow down
500INTERNAL_ERRORSomething went wrong on our end

Addresses

Look up, search, and validate DZ Addresses. Search by DZ# code, full DZ code, or full address string. You can pass the query as a query parameter (?q=...) or directly in the URL path (/search/DZ%23001-01). Ideal for e-commerce checkout integrations.

Dropzons

Search for Dropzon locations, look up full address details for e-commerce checkout, and find the nearest pickup points.

Tracking

Track packages by tracking number and get real-time status updates for shipments.

Locations

Access the Dropzon location hierarchy - countries, regions, cities, and municipalities where Dropzon operates.

Webhooks

Register webhook URLs to receive real-time notifications when package statuses change or deliveries are completed.

Sign in with Dropzon

OAuth 2.0 Authorization Code with PKCE

Overview

“Sign in with Dropzon” lets your users authenticate using their Dropzon account. After authorization, your app receives an access token that can be used to read the user's profile, email, phone, and DZ Address information - depending on the scopes you request.

The implementation follows the OAuth 2.0 Authorization Code flow with optional PKCE (Proof Key for Code Exchange) for public clients like mobile apps and SPAs.

Base URL:https://api.dropzon.app/api/oauth
Grant type:authorization_code

Setup

1

Create an OAuth app

Go to the Developer Console → OAuth Apps and create a new OAuth application.

2

Save your credentials

Copy your client_id (starts with dzo_) and client_secret (starts with dzs_). The secret is only shown once at creation time.

3

Register redirect URIs

Add one or more callback URLs where users will be redirected after authorization. Must be HTTPS in production (http://localhost is allowed for development).

Available Scopes

Request only the scopes your application needs. Users will see a list of requested permissions on the consent screen.

ScopeDescription
profileName and avatar
emailEmail address
phonePhone number
addressPrimary DZ Address
addressesAll DZ Addresses

Authorization Flow

1

Redirect user to Dropzon

Redirect the user's browser to the Dropzon authorization page with your app's parameters.

GET https://dropzon.app/oauth/authorize?
  client_id=dzo_your_client_id
  &redirect_uri=https://yourapp.com/callback
  &response_type=code
  &scope=profile email
  &state=random_csrf_token
  &code_challenge=S256_hash_of_verifier   # optional, for PKCE
  &code_challenge_method=S256              # optional, for PKCE
ParameterDescription
client_idYour OAuth app client ID (dzo_ prefix)
redirect_uriMust match a registered redirect URI
response_typeMust be "code"
scopeSpace-separated scopes (defaults to "profile")
stateRandom string to prevent CSRF attacks
code_challengePKCE challenge (S256 hash of code_verifier)
code_challenge_methodMust be "S256" when using PKCE
2

User signs in and approves

The user sees a consent screen showing your app name, description, and the permissions you're requesting. If they're not logged in, they'll sign in first. After approving, Dropzon redirects them back to your redirect_uri with an authorization code.

3

Handle the callback

Dropzon redirects the user back to your app with a code and state parameter. Verify the state matches what you sent.

https://yourapp.com/callback?code=AUTH_CODE_HERE&state=random_csrf_token

If the user denies access, you'll receive ?error=access_denied&state=... instead. Always check for the error parameter first.

4

Exchange code for tokens

Make a server-side POST request to exchange the authorization code for an access token and refresh token. This request must include your client_secret - never expose it in frontend code.

curl -X POST https://api.dropzon.app/api/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "authorization_code",
    "code": "AUTH_CODE_HERE",
    "redirect_uri": "https://yourapp.com/callback",
    "client_id": "dzo_your_client_id",
    "client_secret": "dzs_your_client_secret",
    "code_verifier": "original_pkce_verifier"  // only if using PKCE
  }'

Response

{
  "success": true,
  "data": {
    "access_token": "dza_...",
    "refresh_token": "dzr_...",
    "token_type": "Bearer",
    "expires_in": 3600,
    "scope": "profile email"
  }
}
5

Get user info

Use the access token to fetch the authenticated user's profile. The response varies based on the granted scopes.

curl https://api.dropzon.app/api/oauth/userinfo \
  -H "Authorization: Bearer dza_your_access_token"

Response (with profile + email scopes)

{
  "success": true,
  "data": {
    "sub": "user-uuid-here",
    "name": "John Mwangi",
    "avatar_url": null,
    "role": "user",
    "email": "john@example.com",
    "email_verified": true
  }
}

Token Management

Token Lifetimes

Access Token

1 hour

Prefix: dza_

Refresh Token

30 days

Prefix: dzr_

Refreshing Tokens

When the access token expires, use the refresh token to get a new pair. The old refresh token is rotated (invalidated) and a new one is returned.

curl -X POST https://api.dropzon.app/api/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "refresh_token",
    "refresh_token": "dzr_your_refresh_token",
    "client_id": "dzo_your_client_id",
    "client_secret": "dzs_your_client_secret"
  }'

Revoking Tokens

Revoke an access or refresh token when the user logs out of your app. Per RFC 7009, this endpoint always returns 200.

curl -X POST https://api.dropzon.app/api/oauth/revoke \
  -H "Content-Type: application/json" \
  -d '{ "token": "dza_or_dzr_token_here" }'

Complete Example- Node.js / Express

const express = require('express');
const crypto = require('crypto');
const app = express();

const CLIENT_ID = 'dzo_your_client_id';
const CLIENT_SECRET = 'dzs_your_client_secret';
const REDIRECT_URI = 'https://yourapp.com/callback';
const OAUTH_AUTHORIZE = 'https://dropzon.app/oauth';  // consent screen (frontend)
const OAUTH_API = 'https://api.dropzon.app/api/oauth';              // token + userinfo (API)

// Step 1: Redirect to Dropzon
app.get('/login', (req, res) => {
  const state = crypto.randomBytes(16).toString('hex');
  req.session.oauthState = state;

  const params = new URLSearchParams({
    client_id: CLIENT_ID,
    redirect_uri: REDIRECT_URI,
    response_type: 'code',
    scope: 'profile email',
    state,
  });

  res.redirect(OAUTH_AUTHORIZE + '/authorize?' + params);
});

// Step 3-4: Handle callback and exchange code
app.get('/callback', async (req, res) => {
  const { code, state, error } = req.query;

  if (error) return res.send('Authorization denied');
  if (state !== req.session.oauthState) return res.status(403).send('Invalid state');

  // Exchange code for tokens
  const tokenRes = await fetch(OAUTH_API + '/token', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      grant_type: 'authorization_code',
      code,
      redirect_uri: REDIRECT_URI,
      client_id: CLIENT_ID,
      client_secret: CLIENT_SECRET,
    }),
  });
  const { data: tokens } = await tokenRes.json();

  // Step 5: Fetch user info
  const userRes = await fetch(OAUTH_API + '/userinfo', {
    headers: { Authorization: 'Bearer ' + tokens.access_token },
  });
  const { data: user } = await userRes.json();

  // user = { sub, name, email, ... }
  req.session.user = user;
  res.redirect('/dashboard');
});

Endpoint Reference

MethodEndpointAuth
GET/oauth/authorizeNone
POST/oauth/tokenNone
GET/oauth/userinfoBearer (access token)
POST/oauth/revokeNone

Security Best Practices

Always validate the state parameter

Compare the state in the callback with the one you sent to prevent CSRF attacks.

Keep client_secret server-side

Never expose your client secret in frontend JavaScript, mobile app binaries, or version control.

Use PKCE for public clients

Single-page apps and mobile apps should use PKCE (code_challenge + code_verifier) since they cannot securely store a client_secret.

Use HTTPS redirect URIs

Always use HTTPS for redirect URIs in production. HTTP is only allowed for localhost during development.

Request minimal scopes

Only request the scopes your application actually needs. Users are more likely to approve fewer permissions.

Handle token expiry gracefully

Use the refresh token flow to renew access tokens. If the refresh token is also expired, redirect the user to re-authorize.

Sign in with Dropzon - Button

Add a branded “Sign in with Dropzon” button to your app. Pick a variant and size below, then copy the code.

Variant

Size

<a href="https://dropzon.app/oauth/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&response_type=code&scope=profile email&state=RANDOM_STATE"
   style="display:inline-flex;align-items:center;gap:10px;height:44px;padding:0 20px;background:#0d84d4;color:#fff;border:none;border-radius:12px;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;font-size:14px;font-weight:600;text-decoration:none;cursor:pointer;transition:opacity 0.15s;"
   onmouseover="this.style.opacity='0.9'" onmouseout="this.style.opacity='1'">
  <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z" fill="#ffffff"/><circle cx="12" cy="9" r="2.5" fill="white"/></svg>
  Sign in with Dropzon
</a>

Branding Guidelines

Use the provided Dropzon pin icon next to the text

Use "Sign in with Dropzon" as the button label

Match one of the four official variants above

Do not stretch, skew, or modify the pin icon

Do not change the button text to other wording

Do not use a font size smaller than 14px

Ready to integrate?

Get your API key and start building with the Dropzon address network. Free tier available for development and testing.