# Activate an adapter

Source: https://convergingthought.com/docs/api-reference/activation

> POST /v1/adapters/activate — change future routing with an expected-version check.



Requires the `adapters` scope. This operation selects a retained version for its owning subject. It is synchronous and returns the resulting route revision; it does not start a training job.

## Customer scope [#customer-scope]

Supply optional `tenant_id` in the body or `X-Internalize-Tenant` in the headers. If both are present they must match. A tenant-restricted key supplies its own tenant when omitted and rejects another tenant. Without either, an unrestricted key uses the separate project namespace. Use the same tenant for learning, inference, job reads, and version changes. See [Serve multiple customers](/docs/guides/multitenancy).

## Request [#request]

```json
{
  "version_id": "CANDIDATE_VERSION_ID",
  "expected_version_id": "CURRENT_ACTIVE_VERSION_ID"
}
```

Both fields are required. `version_id` identifies an existing candidate in the authenticated project. `expected_version_id` is the subject's current active version, or JSON `null` if the subject is still on base. The string `"base"` is not a substitute for `null` in this field.

The subject is determined from the candidate's ownership. You cannot use this endpoint to attach another subject's adapter to a new subject, merge adapters, or change a candidate's owner. Do not send an extra `subject_id` field.

```bash
curl --fail-with-body "$INTERNALIZE_BASE_URL/v1/adapters/activate" \
  -H "Authorization: Bearer $INTERNALIZE_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
    "version_id": "CANDIDATE_VERSION_ID",
    "expected_version_id": null
  }'
```

## Successful response [#successful-response]

```json
{ "version_id": "CANDIDATE_VERSION_ID", "revision": 1 }
```

New requests admitted after activation resolve to this version. Requests already admitted continue using their original snapshot. The revision increments on a successful activation operation. Activating a version that is already active can still increment the revision if the expected version matches; use a read to avoid unnecessary writes.

No additional internalization fee is charged merely for changing the active route. The candidate's earlier training job and its settled charge remain part of history.

## Conflicts [#conflicts]

The operation compares the current active version with `expected_version_id` atomically. A mismatch returns `409 activation_conflict` and does not change routing. Read the subject again and review which update should win.

An automatic retry that simply substitutes the newest expected value would overwrite a concurrent decision without review. Prefer to surface the new current version and your proposed candidate to the release owner or apply a deliberate application policy.

## Network ambiguity [#network-ambiguity]

Manual activation does not use the model-job idempotency mechanism. If the network fails after you submit it, read the subject. If your target is active, the desired route exists; do not repeat the write just to obtain another receipt. If a different version is active, investigate the intervening change before retrying.

## Rollback and expiry [#rollback-and-expiry]

To roll back, use a retained older candidate as `version_id` and the current version as the expected value. The candidate must not be expired. An expired candidate returns `adapter_expired`; an unknown or foreign-project version returns `not_found`.

Rollback affects future inference and future learning parents. It does not erase newer candidates or reverse previous outputs. There is no public reset-to-base operation. See [Deploying updates](/docs/guides/rollouts) for release sequencing and [Retention troubleshooting](/docs/troubleshooting/knowledge) for an expired route.
