> 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

{% 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>

***


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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://docs.admoai.com/api-reference/readme.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.
