# Best Practices Guide

> 💡 **Standards, formats, and recommendations for optimal API usage**

***

## 🌐 Language Format Standards

### Why Language Codes Matter

Using standardized language codes ensures your marketing campaigns reach customers in their preferred language, improving engagement and conversion rates. Proper language tagging also enables accurate analytics and segmentation across global markets.

### IETF Language Tags (BCP 47)

We use the IETF BCP 47 international standard for language identification. This standard is used by HTML, HTTP, and most modern software systems, ensuring compatibility and consistency.

#### Format Pattern

```
language[-script][-region][-variant]
```

#### Common Examples

| Language Tag | Description                   | Usage                      |
| ------------ | ----------------------------- | -------------------------- |
| `en`         | English (generic)             | Default English content    |
| `en-US`      | English (United States)       | US-specific content        |
| `en-GB`      | English (United Kingdom)      | UK-specific content        |
| `es`         | Spanish (generic)             | Default Spanish content    |
| `es-ES`      | Spanish (Spain)               | Spain-specific content     |
| `es-MX`      | Spanish (Mexico)              | Mexico-specific content    |
| `fr`         | French (generic)              | Default French content     |
| `fr-FR`      | French (France)               | France-specific content    |
| `fr-CA`      | French (Canada)               | Canadian French content    |
| `de`         | German (generic)              | Default German content     |
| `de-DE`      | German (Germany)              | Germany-specific content   |
| `de-AT`      | German (Austria)              | Austria-specific content   |
| `pt`         | Portuguese (generic)          | Default Portuguese content |
| `pt-BR`      | Portuguese (Brazil)           | Brazilian Portuguese       |
| `pt-PT`      | Portuguese (Portugal)         | European Portuguese        |
| `it-IT`      | Italian (Italy)               | Italian content            |
| `ja-JP`      | Japanese (Japan)              | Japanese content           |
| `zh-CN`      | Chinese (Simplified, China)   | Simplified Chinese         |
| `zh-TW`      | Chinese (Traditional, Taiwan) | Traditional Chinese        |

#### Best Practices for Language Tags

**1. Be Consistent**\
Use the same format throughout your system. If you use `en-US` in one place, don't use `en` or `en-us` elsewhere.

**2. Start Simple**\
Use basic language codes (`en`, `de`, `fr`) unless regional differences actually matter to your customers. For example:

* Use `en` if content is the same for all English speakers
* Use `en-US` vs `en-GB` only if spelling, dates, or terminology differ

**3. Case Sensitivity**\
Language codes are technically case-insensitive, but follow these conventions for clarity:

* Lowercase for language: `en` (not `EN`)
* Uppercase for region: `US` (not `us`)
* Title case for script: `Hans` (not `HANS`)

**4. Validate Before Sending**\
Validate language tags client-side before API calls to avoid validation errors and ensure data quality.

#### Example Implementation

```javascript
// Valid language tags
const validLanguages = [
  'en',       // English
  'en-US',    // US English
  'en-GB',    // UK English
  'es-ES',    // Spanish (Spain)
  'fr-FR',    // French (France)
  'de-DE',    // German (Germany)
  'pt-BR'     // Portuguese (Brazil)
];

// Validate language tag
function isValidLanguageTag(tag) {
  // Basic pattern: language[-region]
  const pattern = /^[a-z]{2,3}(-[A-Z]{2})?$/;
  return pattern.test(tag);
}

// Example usage
const customer = {
  CustomerId: "C-123",
  Language: "en-US",  // IETF language tag
  GdprOptin: true
};
```

***

## 💰 Currency Format Standards

### Why Currency Codes Matter

Using standardized currency codes ensures accurate financial reporting, proper price display, and compliance with international commerce regulations. It also enables multi-currency analytics and prevents costly errors in pricing logic.

### ISO 4217 Currency Codes

We require currency codes to follow the ISO 4217 international standard - the same standard used by banks, payment processors, and financial systems worldwide.

#### Format Requirements

**Always use 3-letter alphabetic codes**:

* ✅ Correct: `USD`, `EUR`, `GBP`
* ❌ Wrong: `$`, `€`, `USD$`, `dollar`

**Uppercase letters only**:

* ✅ Correct: `USD`
* ❌ Wrong: `usd`, `Usd`

**No currency symbols**:

* ✅ Correct: `USD`, `JPY`
* ❌ Wrong: `$`, `¥`

#### Common Currency Codes

| Code  | Currency           | Country/Region       |
| ----- | ------------------ | -------------------- |
| `USD` | US Dollar          | United States        |
| `EUR` | Euro               | European Union       |
| `GBP` | British Pound      | United Kingdom       |
| `JPY` | Japanese Yen       | Japan                |
| `CHF` | Swiss Franc        | Switzerland          |
| `CAD` | Canadian Dollar    | Canada               |
| `AUD` | Australian Dollar  | Australia            |
| `NZD` | New Zealand Dollar | New Zealand          |
| `CNY` | Chinese Yuan       | China                |
| `INR` | Indian Rupee       | India                |
| `KRW` | South Korean Won   | South Korea          |
| `SGD` | Singapore Dollar   | Singapore            |
| `HKD` | Hong Kong Dollar   | Hong Kong            |
| `MXN` | Mexican Peso       | Mexico               |
| `BRL` | Brazilian Real     | Brazil               |
| `SEK` | Swedish Krona      | Sweden               |
| `NOK` | Norwegian Krone    | Norway               |
| `DKK` | Danish Krone       | Denmark              |
| `PLN` | Polish Złoty       | Poland               |
| `CZK` | Czech Koruna       | Czech Republic       |
| `HUF` | Hungarian Forint   | Hungary              |
| `RUB` | Russian Ruble      | Russia               |
| `ZAR` | South African Rand | South Africa         |
| `TRY` | Turkish Lira       | Turkey               |
| `AED` | UAE Dirham         | United Arab Emirates |

#### Best Practices for Currency Codes

1. **Consistency**: Always use the same currency code format
2. **No Symbols**: Never use currency symbols instead of codes
3. **Validation**: Validate currency codes before submission
4. **Price Handling**: Store prices as decimals with appropriate precision

#### Example Implementation

```javascript
// Valid currency codes
const validCurrencies = [
  'USD', 'EUR', 'GBP', 'JPY', 'AUD', 
  'CAD', 'CHF', 'CNY', 'SEK', 'NOK'
];

// Validate currency code
function isValidCurrencyCode(code) {
  // Must be 3 uppercase letters
  return /^[A-Z]{3}$/.test(code);
}

// Price formatting example
const order = {
  OrderId: "O-789",
  Currency: "USD",    // ISO 4217 code
  TotalRevenue: 99.99,
  OrderItems: [{
    ProductId: "P-42",
    Price: 49.99,     // Decimal, not string
    Currency: "USD"   // Consistent currency
  }]
};

// Multi-currency example
const productVariants = [
  {
    VariantId: "V-100",
    Currency: "USD",
    OriginalPrice: 29.99,
    SalePrice: 24.99
  },
  {
    VariantId: "V-101", 
    Currency: "EUR",
    OriginalPrice: 27.99,
    SalePrice: 22.99
  }
];
```

***

## 📊 Data Quality Best Practices

### 1. Batch Processing

#### Recommended Batch Sizes

| Entity Type | Recommended Size | Maximum Size |
| ----------- | ---------------- | ------------ |
| Customers   | 100-500          | 1000         |
| Orders      | 50-200           | 500          |
| Products    | 50-100           | 200          |

#### Why Batch Sizes Matter

* **Performance**: Larger batches reduce API calls but increase processing time
* **Error Handling**: Smaller batches make error isolation easier
* **Memory Usage**: Large batches consume more memory on both client and server

### 2. Data Validation

#### Pre-submission Validation Checklist

✅ **Required Fields**

* Ensure all required fields are present
* Check for null vs empty string distinctions

✅ **String Lengths**

* Validate against maximum length constraints
* Truncate if necessary (with warnings)

✅ **Data Types**

* Verify correct data types (numbers, booleans, dates)
* Ensure proper date formatting (ISO 8601)

✅ **Business Rules**

* Validate email formats
* Check phone number patterns
* Ensure price consistency

### 3. Error Handling Strategy

```javascript
// Comprehensive error handling example
async function submitDataWithRetry(endpoint, data, maxRetries = 3) {
  const errors = [];
  const successful = [];
  
  for (let batch of chunks(data, BATCH_SIZE)) {
    let retries = 0;
    
    while (retries < maxRetries) {
      try {
        const response = await submitBatch(endpoint, batch);
        
        if (response.success) {
          successful.push(...batch);
          break;
        } else {
          // Handle specific error types
          if (response.status === 400) {
            // Validation error - don't retry
            errors.push({batch, error: response.errors});
            break;
          }
        }
      } catch (error) {
        retries++;
        if (retries === maxRetries) {
          errors.push({batch, error: error.message});
        } else {
          // Exponential backoff
          await sleep(Math.pow(2, retries) * 1000);
        }
      }
    }
  }
  
  return {successful, errors};
}
```

### 4. Identifier Management

#### Customer Identifiers

```javascript
// Best practice: Consistent identifier usage
const customerConfig = {
  identifierPriority: 'customerid', // or 'email'
  
  // Always provide both when possible
  formatCustomer: (customer) => ({
    CustomerId: customer.id,
    Email: customer.email,
    // ... other fields
  })
};
```

#### Product Identifiers

```javascript
// Best practice: Maintain SKU consistency
const productConfig = {
  identifierPriority: 'productid', // or 'sku'
  
  // Ensure variant SKUs are unique
  validateSKUs: (products) => {
    const skus = new Set();
    for (const product of products) {
      for (const variant of product.ProductVariants) {
        if (skus.has(variant.Sku)) {
          throw new Error(`Duplicate SKU: ${variant.Sku}`);
        }
        skus.add(variant.Sku);
      }
    }
  }
};
```

***

## 🔒 Security Best Practices

### 1. API Key Management

* **Store Securely**: Never commit API keys to version control
* **Rotate Regularly**: Change API keys periodically
* **Limit Scope**: Use different keys for different environments
* **Monitor Usage**: Track API key usage for anomalies

### 2. Data Privacy

* **GDPR Compliance**: Always obtain proper consent
* **Data Minimization**: Only send necessary data
* **Anonymization**: Remove PII when not needed
* **Audit Trail**: Log data access and modifications

### 3. Rate Limiting

```javascript
// Implement rate limiting
class RateLimiter {
  constructor(maxRequests, timeWindow) {
    this.maxRequests = maxRequests;
    this.timeWindow = timeWindow;
    this.requests = [];
  }
  
  async executeWithLimit(fn) {
    const now = Date.now();
    this.requests = this.requests.filter(
      time => now - time < this.timeWindow
    );
    
    if (this.requests.length >= this.maxRequests) {
      const oldestRequest = this.requests[0];
      const waitTime = this.timeWindow - (now - oldestRequest);
      await new Promise(resolve => setTimeout(resolve, waitTime));
    }
    
    this.requests.push(now);
    return fn();
  }
}

// Usage
const limiter = new RateLimiter(100, 60000); // 100 requests per minute
await limiter.executeWithLimit(() => api.submitCustomers(data));
```

***

## 🚀 Performance Optimization

### 1. Compression

* Enable gzip compression for requests and responses
* Expect 60-80% size reduction for JSON payloads

### 2. Connection Pooling

* Reuse HTTP connections
* Configure appropriate timeout values
* Monitor connection pool health

### 3. Async Processing

```javascript
// Process multiple entity types in parallel
async function syncAllData(tenantId) {
  const [customers, products, orders] = await Promise.all([
    fetchCustomers(),
    fetchProducts(),
    fetchOrders()
  ]);
  
  // Submit in parallel with error isolation
  const results = await Promise.allSettled([
    api.submitCustomers(tenantId, customers),
    api.submitProducts(tenantId, products),
    api.submitOrders(tenantId, orders)
  ]);
  
  return results.map((result, index) => ({
    type: ['customers', 'products', 'orders'][index],
    status: result.status,
    value: result.value || result.reason
  }));
}
```

***

## 📋 Checklist for Implementation

### Initial Setup

* [ ] Obtain API credentials
* [ ] Configure authentication headers
* [ ] Set up error logging
* [ ] Implement retry logic
* [ ] Configure rate limiting

### Data Preparation

* [ ] Validate all required fields
* [ ] Format dates as ISO 8601
* [ ] Use IETF language tags
* [ ] Use ISO 4217 currency codes
* [ ] Implement batch processing

### Testing

* [ ] Test with minimal data
* [ ] Validate error handling
* [ ] Test rate limit behavior
* [ ] Verify data consistency
* [ ] Monitor performance metrics

### Production

* [ ] Enable monitoring/alerting
* [ ] Set up automated retries
* [ ] Configure backup strategies
* [ ] Document error resolution
* [ ] Plan for scale

***

## 🔗 References

### Standards Documentation

* [IETF BCP 47 - Language Tags](https://tools.ietf.org/html/bcp47)
* [ISO 4217 - Currency Codes](https://www.iso.org/iso-4217-currency-codes.html)
* [ISO 8601 - Date/Time Format](https://www.iso.org/iso-8601-date-and-time-format.html)

### Related Documentation

* [Error Responses Guide](/replenit-docs/error-responses.md)
* [Customers API](/replenit-docs/customers.md)
* [Orders API](/replenit-docs/orders.md)
* [Products API](/replenit-docs/products.md)

### External Resources

* [RFC 7231 - HTTP/1.1 Status Codes](https://tools.ietf.org/html/rfc7231)
* [JSON API Specification](https://jsonapi.org/)
* [REST API Best Practices](https://restfulapi.net/)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://replenit.gitbook.io/replenit-docs/best-practices.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
