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

# Upload context records

> Upload exogenous market conditions the engine should partial out

`POST /api/v2/buyer/advertisers/{advertiserId}/context-records`

Uploads exogenous context data — promos, weather, competitor activity, seasonality — so the learning engine can partial these effects out when estimating incremental impact. Each record covers one geo and time window. Up to 5,000 records per call.

## Request

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.interchange.io/api/v2/buyer/advertisers/12345/context-records \
    -H "Authorization: Bearer $SCOPE3_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "records": [
        {
          "geo": "US-CA",
          "timeWindowStart": "2026-03-01",
          "timeWindowEnd": "2026-03-07",
          "promoActive": true,
          "promoType": "site_wide_15_off",
          "seasonalityIndex": 1.12,
          "flightStatus": "active"
        }
      ]
    }'
  ```
</CodeGroup>

## Parameters

| Field                          | Type    | Required | Notes                                                            |
| ------------------------------ | ------- | -------- | ---------------------------------------------------------------- |
| `advertiserId`                 | string  | Yes      | Path parameter — the owning advertiser                           |
| `records`                      | array   | Yes      | 1–5000 records                                                   |
| `records[].geo`                | string  | Yes      | Geo identifier (e.g. `US-CA`)                                    |
| `records[].timeWindowStart`    | string  | Yes      | Date `YYYY-MM-DD`                                                |
| `records[].timeWindowEnd`      | string  | Yes      | Date `YYYY-MM-DD`                                                |
| `records[].promoActive`        | boolean | No       | Whether a promo ran (default `false`)                            |
| `records[].promoType`          | string  | No       | Free-text promo descriptor                                       |
| `records[].temperatureAvg`     | number  | No       | Average temperature for weather effects                          |
| `records[].competitorActivity` | object  | No       | Free-form competitor signals                                     |
| `records[].seasonalityIndex`   | number  | No       | Seasonality multiplier                                           |
| `records[].flightStatus`       | enum    | No       | `active`, `dark`, `pre_flight`, `post_flight` (default `active`) |

## Response

```json theme={null}
{
  "recordsUploaded": 1
}
```

Returns the count of records uploaded. The endpoint upserts on `(account, advertiser, geo, time window)`, so re-uploading the same key updates in place.

## Errors

* `400 VALIDATION_ERROR` — empty `records`, more than 5,000 records, a missing required field, or a malformed date.
* `404 NOT_FOUND` — `advertiserId` does not exist or is not visible to the authenticated account.

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

## Related

<CardGroup cols={2}>
  <Card title="Measurement tasks" href="/v2/buyer/measurement/tasks" icon="list-check">
    All measurement operations
  </Card>

  <Card title="Measurement overview" href="/v2/guides/measurement-incrementality" icon="chart-line">
    Pipeline, belief state, and concepts
  </Card>

  <Card title="Upload measurement records" href="/v2/buyer/measurement/tasks/upload-measurement-records" icon="upload">
    Upload outcome records
  </Card>
</CardGroup>
