> ## 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.

# Create feed-backed modular source

> Create a modular source for seller-uploaded avails feeds

`POST /api/v2/storefront/inventory-sources/modular/feed`

Creates a real `MODULAR_SOURCE` for sellers who manage availability through a
spreadsheet, export, or manual feed rather than a live ad-server integration.
The source is created with the built-in avails-feed module and, by default, the
built-in booking ledger.

This endpoint does not attach arbitrary execution, reporting, creative, or OMS
adapters. Those details can be stored as non-secret setup metadata until a
matching module exists.

## Request

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.interchange.io/api/v2/storefront/inventory-sources/modular/feed \
    -H "Authorization: Bearer $SCOPE3_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "sourceId": "reachafrica-ctv",
      "name": "ReachAfrica CTV Avails",
      "availsSource": {
        "type": "spreadsheet",
        "cadence": "monthly",
        "description": "Seller uploads monthly South Africa CTV avails"
      },
      "booking": {
        "mode": "booking_ledger"
      },
      "execution": {
        "mode": "manual",
        "systemName": "Seller ops"
      },
      "reporting": {
        "mode": "upload",
        "sampleAvailable": true
      },
      "creative": {
        "mode": "manual",
        "notes": "Human review confirms broadcast specs"
      }
    }'
  ```
</CodeGroup>

## Parameters

| Field                       | Type    | Required | Notes                                                                                                         |
| --------------------------- | ------- | -------- | ------------------------------------------------------------------------------------------------------------- |
| `name`                      | string  | Yes      | Seller-facing source name, 1-255 characters                                                                   |
| `sourceId`                  | string  | No       | Storefront-scoped ID. Lowercase letters, numbers, dashes, or underscores only. Defaults to a slugified `name` |
| `includeBookingLedger`      | boolean | No       | Defaults to `true`. Set `false` only when Interchange should not hold capacity against this feed              |
| `availsSource.type`         | enum    | No       | `upload`, `spreadsheet`, `api`, `manual`, or `unknown`                                                        |
| `availsSource.cadence`      | string  | No       | Human-readable update cadence, such as `monthly`                                                              |
| `availsSource.description`  | string  | No       | Non-secret feed description                                                                                   |
| `booking.mode`              | enum    | No       | `booking_ledger`, `manual`, or `upstream_oms`                                                                 |
| `booking.systemName`        | string  | No       | Non-secret OMS or booking system name                                                                         |
| `booking.notes`             | string  | No       | Non-secret booking notes                                                                                      |
| `execution.mode`            | enum    | No       | `manual`, `upstream_system`, or `none`                                                                        |
| `execution.systemName`      | string  | No       | Non-secret execution system name                                                                              |
| `reporting.mode`            | enum    | No       | `upload`, `manual`, `upstream_export`, `api`, or `none`                                                       |
| `reporting.systemName`      | string  | No       | Non-secret reporting system name                                                                              |
| `reporting.sampleAvailable` | boolean | No       | Whether the seller has provided or can provide a sample report export                                         |
| `creative.mode`             | enum    | No       | `manual`, `upstream_system`, or `none`                                                                        |
| `creative.systemName`       | string  | No       | Non-secret creative workflow system name                                                                      |
| `notes`                     | string  | No       | Non-secret setup notes                                                                                        |

<Warning>
  Do not send secrets in this request. API keys, login credentials, private keys,
  and service-account files must use the appropriate credential flow for the
  module or ad-server connection.
</Warning>

## Response

`201 Created` with the new source id and modular runtime projection:

```json theme={null}
{
  "inventorySourceId": "900222",
  "sourceId": "reachafrica-ctv",
  "projection": {
    "inventorySource": {
      "id": "900222",
      "sourceId": "reachafrica-ctv",
      "name": "ReachAfrica CTV Avails",
      "executionType": "MODULAR_SOURCE",
      "status": "ACTIVE",
      "healthStatus": "healthy"
    },
    "modules": [
      {
        "moduleInstanceId": "static-avails-feed",
        "kind": "INVENTORY_FEED",
        "provider": "agentic",
        "status": "ACTIVE"
      },
      {
        "moduleInstanceId": "booking-ledger",
        "kind": "BOOKING_LEDGER",
        "provider": "agentic",
        "status": "ACTIVE"
      }
    ],
    "activeAvailCount": 0,
    "openWorkItemCount": 0
  }
}
```

After creating the source, upload or paste avails into
`POST /api/v2/storefront/inventory-sources/{sourceId}/modular/avails-feed`.
Preview normalized rows first, then commit only after confirming row grain and
net sellable capacity.

## Errors

* `400 VALIDATION_ERROR` — missing `name` or invalid `sourceId`.
* `401 UNAUTHORIZED` — missing or invalid API key.
* `404 NOT_FOUND` — the caller does not have a storefront.
* `409 CONFLICT` — another active source already uses the same `sourceId`.

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

## Related

<CardGroup cols={2}>
  <Card title="Modular lifecycle" href="/v2/storefront/inventory-sources/modular-lifecycle" icon="diagram-project">
    How feed, booking, HITL, and reporting stages fit together
  </Card>

  <Card title="Get modular readiness" href="/v2/storefront/inventory-sources/tasks/get-modular-readiness" icon="diagram-project">
    Inspect modules and lifecycle status
  </Card>

  <Card title="Update module config" href="/v2/storefront/inventory-sources/tasks/update-modular-module-config" icon="sliders">
    Update non-secret module setup
  </Card>

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