> ## Documentation Index
> Fetch the complete documentation index at: https://docs.interchange.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Rotate ad-server credentials

> Rotate credentials in place on an already-provisioned ad-server source

`PUT /api/v2/storefront/inventory-sources/{sourceId}/adapter-config`

Rotates credentials on an already-provisioned ad-server source without re-provisioning. Products, principals, and sync history survive the rotation. Use this for FreeWheel and SpringServe, whose credentials rotate — Google Ad Manager rotation uses [Replace ad-server config](/v2/storefront/inventory-sources/tasks/replace-ad-server-config) since Scope3 manages those credentials.

## Request

<CodeGroup>
  ```bash FreeWheel theme={null}
  curl -X PUT https://api.interchange.io/api/v2/storefront/inventory-sources/retail-fw/adapter-config \
    -H "Authorization: Bearer $SCOPE3_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "freewheel",
      "clientId": "fw-client-id",
      "clientSecret": "<NEW_FREEWHEEL_CLIENT_SECRET>",
      "environment": "production"
    }'
  ```

  ```json SpringServe theme={null}
  {
    "type": "springserve",
    "email": "ops@retail-network.example.com",
    "password": "<NEW_SPRINGSERVE_PASSWORD>",
    "environment": "production"
  }
  ```
</CodeGroup>

## Parameters

Same `AdServerConfig` body as [Replace ad-server config](/v2/storefront/inventory-sources/tasks/replace-ad-server-config). The `type` discriminator selects the adapter; supply the rotated credentials for that adapter.

| Field      | Type          | Required | Notes                                              |
| ---------- | ------------- | -------- | -------------------------------------------------- |
| `sourceId` | string (path) | Yes      | Storefront-scoped inventory source ID              |
| `type`     | enum          | Yes      | `google_ad_manager`, `freewheel`, or `springserve` |

<Warning>
  New `clientSecret`, `password`, and `apiToken` values are forwarded to the managed ad-server source and never persisted by Scope3. Treat them as production secrets — never log or commit them.
</Warning>

## Response

`200 OK` with the updated `EsaConnection` (same shape as [Get ad-server connection](/v2/storefront/inventory-sources/tasks/get-ad-server-connection)):

```json theme={null}
{
  "id": "550200",
  "customerId": 4210,
  "tenantId": "tnt_retail_fw",
  "adServer": {
    "type": "freewheel",
    "clientId": "fw-client-id",
    "username": null,
    "environment": "production",
    "defaultAdvertiserId": null
  },
  "serviceAccountEmail": null,
  "lastError": null,
  "lastErrorCode": null,
  "lastTestedAt": "2026-05-02T09:30:00Z",
  "updatedAt": "2026-05-02T09:30:00Z"
}
```

## Errors

* `400 VALIDATION_ERROR` — unknown `type` or missing credentials for the adapter.
* `401 UNAUTHORIZED` — missing or invalid API key.
* `404 NOT_FOUND` — no ad-server-backed source with this `sourceId`.

See [Errors](/v2/reference/errors) for the full error contract.

## Related

<CardGroup cols={2}>
  <Card title="Inventory source tasks" href="/v2/storefront/inventory-sources/tasks" icon="list-check">
    All operations
  </Card>

  <Card title="Replace ad-server config" href="/v2/storefront/inventory-sources/tasks/replace-ad-server-config" icon="gear">
    Set the full config (and GAM rotation)
  </Card>

  <Card title="Test connection" href="/v2/storefront/inventory-sources/tasks/test-connection" icon="plug-circle-check">
    Verify the rotated credentials
  </Card>

  <Card title="Get ad-server connection" href="/v2/storefront/inventory-sources/tasks/get-ad-server-connection" icon="server">
    Connection state
  </Card>
</CardGroup>
