Skip to main content

Overview

The Zochil API uses token-based authentication with access tokens and device IDs. All API requests must include proper authentication headers to access protected resources.

Authentication Methods

Access Token Authentication

Most API endpoints require an access-token header:
curl -H "access-token: your_access_token_here" \
     -H "device-id: your_device_id_here" \
     https://api.zochil.io/user/profile

Admin Authentication

Admin endpoints also require a merchant-id header:
curl -H "access-token: admin_access_token" \
     -H "device-id: admin_device_id" \
     -H "merchant-id: merchant_uuid" \
     https://api.zochil.io/admin/users

Required Headers

access-token
string
required
JWT token for user authentication. Obtained from login or registration endpoints.
device-id
string
required
Unique identifier for the client device. Used for session management and security.
merchant-id
string
Required for admin and order API endpoints. Identifies the merchant/shop context.

User Authentication Flow

1. User Registration

curl -X POST "https://api.zochil.io/user/register" \
  -H "Content-Type: application/json" \
  -H "device-id: unique_device_id" \
  -d '{
    "email": "[email protected]",
    "password": "secure_password",
    "name": "John Doe",
    "phone": "+1234567890"
  }'

2. User Login

curl -X POST "https://api.zochil.io/user/login" \
  -H "Content-Type: application/json" \
  -H "device-id: unique_device_id" \
  -d '{
    "email": "[email protected]",
    "password": "secure_password"
  }'

3. Using the Access Token

Once you have an access token, include it in all subsequent requests:
const userProfile = await fetch("https://api.zochil.io/user/profile", {
  headers: {
    "access-token": access_token,
    "device-id": "unique_device_id"
  }
});

Admin Authentication

Admin users have additional privileges and can access merchant-specific data:
// Admin login
const adminResponse = await fetch("https://api.zochil.io/admin/login", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "device-id": "admin_device_id"
  },
  body: JSON.stringify({
    email: "[email protected]",
    password: "admin_password"
  })
});

const { access_token, user } = await adminResponse.json();

// Access merchant data
const merchantData = await fetch("https://api.zochil.io/admin/dashboard", {
  headers: {
    "access-token": access_token,
    "device-id": "admin_device_id",
    "merchant-id": user.merchant_id
  }
});

Token Storage and Management

Token Storage

  • User tokens: Stored in Redis with expiration
  • Admin tokens: Stored in Redis with role-based metadata
  • Device tokens: Stored in the devices table for session tracking

Token Expiration

  • Tokens typically expire after 24 hours
  • Refresh tokens may be available for long-lived sessions
  • Always handle token expiration gracefully in your application

Security Best Practices

Never expose access tokens in client-side code or URLs. Always store tokens securely and transmit them over HTTPS.
  1. Secure Storage: Store tokens in secure, HTTP-only cookies or encrypted local storage
  2. HTTPS Only: Always use HTTPS for API requests containing tokens
  3. Token Rotation: Implement token refresh mechanisms for long-lived applications
  4. Device Management: Generate unique device IDs for each client installation
  5. Logout Handling: Properly invalidate tokens on logout

Example Secure Implementation

class ZochilAPIClient {
  constructor() {
    this.baseURL = "https://api.zochil.io";
    this.accessToken = this.getSecureToken();
    this.deviceId = this.getOrCreateDeviceId();
  }

  getSecureToken() {
    // Retrieve from secure storage
    return localStorage.getItem("zochil_access_token");
  }

  getOrCreateDeviceId() {
    let deviceId = localStorage.getItem("zochil_device_id");
    if (!deviceId) {
      deviceId = this.generateUUID();
      localStorage.setItem("zochil_device_id", deviceId);
    }
    return deviceId;
  }

  async makeRequest(endpoint, options = {}) {
    const response = await fetch(`${this.baseURL}${endpoint}`, {
      ...options,
      headers: {
        "Content-Type": "application/json",
        "access-token": this.accessToken,
        "device-id": this.deviceId,
        ...options.headers
      }
    });

    if (response.status === 401) {
      // Handle token expiration
      this.handleTokenExpiration();
      throw new Error("Authentication required");
    }

    return response.json();
  }
}

Error Handling

Common authentication errors and their meanings:
Status CodeError CodeDescription
401UNAUTHORIZEDInvalid or expired access token
401MISSING_TOKENAccess token not provided
401INVALID_DEVICEDevice ID not recognized
403INSUFFICIENT_PERMISSIONSUser lacks required permissions
403MERCHANT_ACCESS_DENIEDInvalid merchant context

Next Steps