> For the complete documentation index, see [llms.txt](https://docs.admoai.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.admoai.com/api-reference/readme.md).

# API Versioning & Upgrade Policy

Learn more about our API versioning and upgrade policies

{% hint style="success" %}
Platform Stability Commitment

Admoai follows a **"minimize versions"** philosophy inspired by SaaS industry leaders. We evolve continuously without forcing disruptive migrations on our customers.
{% endhint %}

### Version Status Dashboard

| Version        | Release Date | Current Phase | Support Until | Status             |
| -------------- | ------------ | ------------- | ------------- | ------------------ |
| **2025-11-01** | Nov 1, 2025  | Active        | Nov 1, 2026+  | 🟢 **Recommended** |
| **2025-01-01** | Jan 1, 2025  | Active        | Jan 1, 2026+  | 🟢 **Supported**   |

***

### Overview

At Admoai, we believe that **API stability and continuous innovation are not mutually exclusive**. Our versioning strategy is designed to:

* **Maximize backward compatibility** across releases
* **Minimize breaking changes** that require customer action
* **Enable rapid feature delivery** without version sprawl
* **Reduce integration maintenance burden** for developers

This document outlines our versioning policy and the expectations we have for API integrators.

***

### Version Philosophy

#### The Problem with Traditional Versioning

Many platforms follow a traditional versioning approach where:

* Each major change requires a **new version** (v1, v2, v3...)
* Customers must **rewrite integrations** to adopt new features
* Old versions become **deprecated quickly**, forcing migrations
* Teams spend more time on **maintenance than innovation**

**Result**: High integration costs, migration fatigue, and slower feature adoption.

#### Our "Minimize Versions" Approach

Admoai takes a different path:

* **Additive changes only**: New fields and features are added, existing ones remain stable
* **Long version lifecycles**: Versions remain active for 12+ months minimum
* **Graceful evolution**: Changes are designed for zero-downtime adoption
* **Clear migration paths**: When changes are needed, we provide comprehensive guides

**Result**: Lower total cost of ownership, faster time-to-value, predictable upgrade cycles.

***

### How Versions Work

#### Date-Based Versioning

We use **calendar versioning** in the format `YYYY-MM-DD`:

```http
X-Decision-Version: 2025-11-01
X-Tracking-Version: 2025-11-01
```

**Benefits**:

* **Transparent**: Version date = feature freeze date
* **Predictable**: Easy to understand age and support status
* **Flexible**: Allows targeted updates without full API rewrites

#### Version Selection

Clients specify their version via HTTP headers:

```bash
curl -X POST https://api.admoai.com/v1/decision \
  -H "X-Decision-Version: 2025-11-01" \
  -H "Content-Type: application/json" \
  -d '{"placements": [{"key": "banner"}]}'
```

```javascript
fetch('https://api.admoai.com/v1/decision', {
  method: 'POST',
  headers: {
    'X-Decision-Version': '2025-11-01',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    placements: [{ key: 'banner' }]
  })
})
```

```swift
var request = URLRequest(url: url)
request.setValue("2025-11-01", forHTTPHeaderField: "X-Decision-Version")
request.httpMethod = "POST"
```

```kotlin
val request = Request.Builder()
    .url("https://api.admoai.com/v1/decision")
    .addHeader("X-Decision-Version", "2025-11-01")
    .post(requestBody)
    .build()
```

{% hint style="warning" %}
&#x20;Default Behavior

If no version header is provided, the system defaults to the **oldest active version** for maximum backward compatibility.
{% endhint %}

***

### Tolerant Reader Policy

To maintain our minimize-versions philosophy, we require all API integrators to follow the **Tolerant Reader Pattern**. This industry-standard practice ensures your integration remains resilient to non-breaking API evolution.

#### What is Tolerant Reader?

The Tolerant Reader Pattern means your code should:

* **Accept more than it expects**
* **Ignore what it doesn't understand**
* **Validate only what matters to its logic**

***

### The Four Golden Rules

#### Rule 1: Ignore Unknown Fields

**Requirement**: Your code MUST ignore JSON fields it doesn't recognize.

```javascript
// ✅ GOOD: Only extract fields you need
const { placement, creatives } = response.data[0];

creatives.forEach(creative => {
  const { contents, tracking } = creative;
  // Unknown fields like "newField" are safely ignored
});
```

```javascript
// ❌ BAD: Strict schema validation fails on new fields
const schema = {
  placement: String,
  creatives: Array
  // Adding "newField" here breaks your code
};

validate(response.data[0], schema); // Throws on unknown fields!
```

**Why**: We add new fields frequently (e.g., metadata, analytics hints). Your integration shouldn't break when we ship improvements.

**Example**: When we added `metadata.duration` for video ads, integrations following this rule continued working seamlessly.

***

#### Rule 2: Handle Unexpected Enum Values

**Requirement**: Treat enumerations as open sets, not closed lists.

```javascript
// ✅ GOOD: Defensive enum handling with fallback
switch (creative.delivery) {
  case 'json':
    renderJSON(creative);
    break;
  case 'vast_tag':
    renderVASTTag(creative);
    break;
  case 'vast_xml':
    renderVASTXML(creative);
    break;
  default:
    // Graceful fallback for unknown delivery modes
    console.warn(`Unknown delivery mode: ${creative.delivery}`);
    renderDefault(creative);
}
```

```javascript
// ❌ BAD: Crashes on unknown enum values
const DELIVERY_MODES = ['json', 'vast_tag', 'vast_xml'];

if (!DELIVERY_MODES.includes(creative.delivery)) {
  throw new Error(`Invalid delivery mode: ${creative.delivery}`);
}
```

**Why**: We may introduce new enum values (e.g., new delivery modes, event types, targeting options) without bumping the version.

**Example**: If we add `vast_wrapper` delivery mode, your integration should handle it gracefully, not crash.

***

#### Rule 3: Treat Objects as Extensible

**Requirement**: Don't assume JSON objects have a fixed structure.

```typescript
// ✅ GOOD: Access only known properties
interface Creative {
  contents: Content[];
  tracking: Tracking;
  advertiser: Advertiser;
  // Allow additional properties
  [key: string]: any;
}

function renderCreative(creative: Creative) {
  // Works with current and future fields
  const { contents, tracking } = creative;
}
```

```typescript
// ❌ BAD: Exact type matching fails on new fields
interface Creative {
  contents: Content[];
  tracking: Tracking;
  advertiser: Advertiser;
  // No additional properties allowed!
}

function renderCreative(creative: Creative) {
  // TypeScript error if API adds new fields
}
```

**Why**: We extend objects with new optional fields (e.g., adding `metadata` to `Creative`). Your schema validation shouldn't reject responses with extra data.

**Pro Tip**: Use TypeScript's `Pick<>` or `Partial<>` utilities to select only the fields you need.

***

#### Rule 4: Validate Only What Matters

**Requirement**: Validate business logic constraints, not API contract completeness.

```javascript
// ✅ GOOD: Validate your business requirements only
function canDisplayAd(creative) {
  // Check what YOUR app needs
  if (!creative.contents || creative.contents.length === 0) {
    return false;
  }
  
  if (!creative.tracking?.impressions?.[0]?.url) {
    return false;
  }
  
  // Don't validate fields you don't use
  return true;
}
```

```javascript
// ❌ BAD: Over-validation breaks when API evolves
function canDisplayAd(creative) {
  // Fails if API adds new required fields
  const required = [
    'contents', 'tracking', 'advertiser', 
    'template', 'metadata'
  ];
  
  return required.every(field => 
    creative[field] !== undefined
  );
}
```

**Why**: We may add new required fields that don't affect your use case. Over-validation creates artificial breaking changes.

**Best Practice**: Validate the **minimum viable data** needed for your feature, nothing more.

***

### Change Types & Compatibility

#### Additive Changes (Non-Breaking)

These changes **do NOT require** a new version:

| Change Type         | Example                             | Your Action                         |
| ------------------- | ----------------------------------- | ----------------------------------- |
| New optional field  | Adding `metadata.format`            | None (ignored automatically)        |
| New enum value      | Adding `"vast_wrapper"` to delivery | Handle gracefully with default case |
| New endpoint        | Adding `POST /v1/analytics`         | None (opt-in when ready)            |
| New response object | Adding `recommendations` array      | None (ignored automatically)        |
| New error code      | Adding error code `10999`           | Handle as generic error             |
| New warning         | Adding new warning type             | Log and continue                    |

{% hint style="success" %}
Zero-Downtime Adoption

Additive changes are designed for **zero-downtime adoption**. Update when convenient, not urgently.
{% endhint %}

#### Breaking Changes (Version Bump Required)

These changes **require** a new version:

| Change Type         | Example                        | Mitigation                      |
| ------------------- | ------------------------------ | ------------------------------- |
| Removing field      | Removing `metadata.language`   | 12-month deprecation notice     |
| Changing field type | `count: string → number`       | New version + migration guide   |
| Renaming field      | `user.id → user.userId`        | New version + mapping docs      |
| Removing enum value | Removing `"legacy"` delivery   | 12-month deprecation notice     |
| Changing validation | Making optional field required | New version + transition period |

{% hint style="warning" %}
Breaking Change Policy

Breaking changes trigger a **new API version** with:

* **12+ months** of parallel support
* **Migration guide** with code examples
* **Deprecation warnings** in old version responses
* **Automated migration tools** (when feasible)
  {% endhint %}

***

### Version Lifecycle

#### Phase Definitions

**1. Active Phase (12+ months)**

* **Full feature support**: New features added
* **Bug fixes**: Issues resolved promptly
* **Performance improvements**: Optimizations applied
* **Security updates**: Patches applied immediately
* **Documentation updates**: Kept current

{% hint style="success" %}
Recommended Integrate new projects with the **latest Active version**.
{% endhint %}

**2. Maintenance Phase (6 months)**

* **Bug fixes**: Critical issues only
* **Security updates**: Patches applied immediately
* ⚠️ **No new features**: Feature development frozen
* ⚠️ **Migration encouraged**: Start planning upgrade

{% hint style="warning" %}
Deprecation Warning

Responses include `X-API-Deprecated: true` header with sunset date.
{% endhint %}

**3. Deprecated Phase (3 months)**

* **Security updates**: Critical patches only
* ⚠️ **No bug fixes**: Non-security issues not addressed
* ⚠️ **Limited support**: Best-effort support only
* 🔴 **Sunset date announced**: Hard deadline communicated

{% hint style="danger" %}
Action Required&#x20;

**Migrate immediately** to avoid service disruption.
{% endhint %}

**4. Sunset (End of Life)**

* 🔴 **Service terminated**: API version no longer accepted
* 🔴 **Requests rejected**: HTTP 410 Gone returned
* 🔴 **No support**: Integration assistance unavailable

{% hint style="danger" %}
Breaking Change&#x20;

Requests with sunset version headers return

```
{
  "success": false,
  "errors": [{
    "code": 10043,
    "message": "API version 2024-01-01 is no longer supported. Please upgrade to 2025-01-01 or later.",
    "details": {
      "deprecated_version": "2024-01-01",
      "active_versions": ["2025-01-01", "2025-11-01"],
      "migration_guide": "https://docs.admoai.com/migration-guide"
    }
  }]
}
```

{% endhint %}

***

### Best Practices for Integrators

#### 1. Version Pinning Strategy

**Recommendation: Pin to a Specific Version**

```javascript
// ✅ GOOD: Explicit version pinning
const ADMOAI_VERSION = '2025-11-01';

fetch(API_URL, {
  headers: {
    'X-Decision-Version': ADMOAI_VERSION
  }
});
```

**Why**:

* Predictable behavior across deployments
* Controlled upgrade timing
* Easier debugging and testing

{% hint style="warning" %}
Dont Rely on Defaults&#x20;

Relying on the default version can lead to unpredictable behavior when defaults change.
{% endhint %}

***

#### 2. Defensive Programming

**Always Use Optional Chaining**

```javascript
// ✅ GOOD: Safe property access
const duration = creative.metadata?.duration;
const videoUrl = creative.contents
  ?.find(c => c.key === 'video_asset')
  ?.value;

// ❌ BAD: Assumes structure
const duration = creative.metadata.duration; // Crashes if missing
```

**Why**: Protects against schema evolution and missing fields.

***

#### 3. Graceful Degradation

**Provide Fallbacks for Unknown Values**

```javascript
// ✅ GOOD: Fallback for unknown delivery modes
function renderAd(creative) {
  switch (creative.delivery) {
    case 'json':
      return renderJSON(creative);
    case 'vast_tag':
      return renderVASTTag(creative);
    default:
      // Fallback to safe default
      console.warn(`Unknown delivery: ${creative.delivery}`);
      return renderFallback(creative);
  }
}
```

**Why**: Maintains service continuity during API evolution.

***

#### 4. Monitor Warnings

**Log and Track API Warnings**

```javascript
// ✅ GOOD: Track warnings for observability
if (response.warnings && response.warnings.length > 0) {
  response.warnings.forEach(warning => {
    logger.warn('Admoai API Warning', {
      code: warning.code,
      message: warning.message,
      details: warning.details
    });
    
    // Send to monitoring system
    metrics.increment('admoai.api.warnings', {
      code: warning.code
    });
  });
}
```

**Why**: Early detection of upcoming changes or integration issues.

{% hint style="success" %}
Proactive Monitoring

Set up alerts for API warnings to catch potential issues before they become problems.
{% endhint %}

***

#### 5. Automated Testing Across Versions

**Test Against Multiple Versions in CI/CD**

```yaml
# .github/workflows/test.yml
- name: Test Admoai Integration
  strategy:
    matrix:
      api_version: ['2025-01-01', '2025-11-01']
  run: |
    export ADMOAI_VERSION=${{ matrix.api_version }}
    npm test
```

**Why**: Ensures smooth version transitions and catches breaking changes early.

***

### Migration Process

When we release a new version, here's what happens:

#### Step 1: Announcement (T-90 days)

* **Email/Slack notification** to all registered developers
* **Migration guide** published with code examples

#### Step 2: Parallel Support (T-0 to T+12 months)

* **Both versions active**: Old and new versions fully supported
* **No forced migration**: Integrate on your timeline
* **Testing period**: Validate new version in staging
* **Support available**: Engineering assistance via Slack/email

#### Step 3: Maintenance Phase (T+12 to T+15 months)

* ⚠️ **Old version enters maintenance**: Feature freeze
* ⚠️ **Deprecation warnings**: Headers added to responses
* ⚠️ **Migration encouraged**: Upgrade before sunset
* **Security updates**: Still applied to old version

#### Step 4: Deprecation Notice (T+15 months)

* 🔴 **Sunset date announced**: 90-day hard deadline
* 🔴 **Aggressive warnings**: Email + in-response notices
* 🔴 **Support limited**: Best-effort only
* **Migration tooling**: Automated upgrade scripts (if applicable)

#### Step 5: Sunset (T+18 months)

* 🔴 **Version terminated**: HTTP 410 Gone for old version
* 🔴 **Breaking change**: Must upgrade to continue service
* **New version mature**: 12+ months of production use

{% hint style="info" %}
Migration Timeline **Minimum 21 months** from new version release to old version sunset.
{% endhint %}

***

### SDK Version Alignment

Our official SDKs automatically handle versioning:

```javascript
import { AdmoaiClient } from '@admoai/sdk';

const client = new AdmoaiClient({
  // SDK handles version automatically
  version: '2025-11-01' // Optional override
});
```

```swift
import Admoai

let client = AdmoaiClient(
  // SDK defaults to compatible version
  version: "2025-11-01" // Optional override
)
```

```kotlin
import com.admoai.sdk.AdmoaiClient

val client = AdmoaiClient.Builder()
  // SDK manages version lifecycle
  .version("2025-11-01") // Optional override
  .build()
```

**SDK Version Strategy**:

* **Major SDK version** = API version (e.g., SDK v2025.11.x → API v2025-11-01)
* **Automatic upgrades**: Minor/patch updates maintain compatibility
* **Migration notices**: Breaking SDK updates include upgrade guides

***

### Frequently Asked Questions

#### Q: What if I need a feature from a new version?

**Answer:**

Simply update your version header to the new version:

```diff
- X-Decision-Version: 2025-01-01
+ X-Decision-Version: 2025-11-01
```

**If using SDK**: Update to newer SDK version:

```diff
- "@admoai/sdk": "^2025.1.0"
+ "@admoai/sdk": "^2025.11.0"
```

***

#### Q: Can I use different versions for different endpoints?

**Answer:**

Yes! Version headers are **per-request**:

```javascript
// Decision API on new version
fetch('/v1/decision', {
  headers: { 'X-Decision-Version': '2025-11-01' }
});

// Tracking API on old version (if needed)
fetch('/v1/tracking', {
  headers: { 'X-Tracking-Version': '2025-01-01' }
});
```

This allows **gradual migration** per endpoint/feature.

***

#### Q: How do I know when to upgrade?

**Indicators it's time to upgrade:**

1. Response includes deprecation warning header
2. Email notification about upcoming sunset
3. New features you want to adopt
4. Bug fixes only available in newer version

**When NOT to upgrade:**

* Current version in Active phase
* No features needed from new version
* No deprecation warnings received

***

#### Q: What happens if I don't upgrade before sunset?

**Answer:**

Your API requests will fail with HTTP 410 Gone:

```json
{
  "success": false,
  "errors": [{
    "code": 10043,
    "message": "Version 2024-01-01 is no longer supported",
    "details": {
      "sunset_date": "2026-01-01",
      "migration_guide": "https://docs.admoai.com/..."
    }
  }]
}
```

{% hint style="danger" %}
Prevention Strategy

We send **multiple warnings** 90, 60, 30, and 7 days before sunset. Don't ignore them!
{% endhint %}

***

#### Q: Do you support version ranges (e.g., `>=2025-01-01`)?

**Answer:**

**No**. We require **exact version** for predictability:

```http
X-Decision-Version: 2025-11-01
❌ X-Decision-Version: >=2025-01-01
❌ X-Decision-Version: latest
```

**Why**:

* Ensures reproducible behavior
* Prevents unexpected breaking changes
* Enables better caching and routing

***

### Contact & Support

Need help with versioning or migration?

* **Technical Support**: <support@admoai.com>

***
