# Upload Demand Data

## Upload Demand Data

> Beam Analyses support daily or weekly demand data. The type of data is detected automatically on upload.\
> \
> For \*\*daily\*\* demand the minimum amount of data required is \*\*6 months\*\*, or 180 data points. Beam can impute up \
> to 20% of missing values, provided that the minimum data requirements are satisfied and there are no more than 7 \
> consecutive days missing.\
> \
> For \*\*weekly\*\* demand the minimum amount of data required is \*\*2 years\*\*, or 104 data points. Beam can impute up \
> to 10% of missing values, provided that the minimum data requirements are satisfied and there are no more than 5 \
> consecutive weeks missing. All weekly data points must align with the \*\*start of the week\*\* and occur on the \
> same weekday.\
> \
> All data points need to be between 2017-01-01 and one year into the future from today's date (today + 365 days).\
> \
> Uploading data replaces existing data for the same date. It's not currently possible to remove data for a \
> particular date. The idea with this endpoint is that you're continuously adding new demand data over time.\
> \
> The data can be uploaded in chunks, but the analysis data must remain valid at all times. If a newly uploaded \
> chunk renders the analysis data invalid (for example, by introducing a large gap between data points), the \
> chunk will be rejected, and the previously stored demand data will be preserved.

```json
{"openapi":"3.1.0","info":{"title":"PredictHQ Beam API","version":"1.0.0"},"tags":[{"name":"Analyses"}],"servers":[{"url":"https://api.predicthq.com"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"$API_KEY","description":"Enter your PredictHQ API key. The Bearer prefix is added automatically.\n\nWhen calling the API directly, send: `Authorization: Bearer <YOUR_API_KEY>` as documented at [https://docs.predicthq.com/api/overview/authenticating](https://docs.predicthq.com/api/overview/authenticating)\n"}},"requestBodies":{"UploadDemandData":{"description":"Upload demand data in CSV, newline-delimited JSON (NDJSON), or JSON formats.","required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DemandDataPoint"}},"application/x-ldjson":{"schema":{"description":"Deprecated. Same format as application/x-ndjson (newline-delimited JSON objects).","type":"string"}},"application/x-ndjson":{"schema":{"description":"Newline-delimited JSON where each line is an object with date and demand.","type":"string"}},"text/csv":{"schema":{"description":"CSV with lowercase headers date,demand and multiple rows of values.","type":"string"}}}}},"schemas":{"DemandDataPoint":{"description":"A single demand data point consisting of a date and a positive numeric demand value.","type":"object","properties":{"date":{"description":"ISO8601 Date format (YYYY-MM-DD)","type":"string","format":"date"},"demand":{"description":"Number value (float or integer, must be a positive number).","type":"number","exclusiveMinimum":0}},"required":["date","demand"]},"HTTPError":{"type":"object","properties":{"error":{"description":"A human-readable error message.","type":"string","title":"Error"}},"required":["error"],"title":"HTTPError"},"UploadErrorResponse":{"description":"An unsuccessful HTTP response code could be returned for several reasons. In addition to an error message, there may\nalso be a `code` field when applicable.\n","oneOf":[{"$ref":"#/components/schemas/content_type_invalid"},{"$ref":"#/components/schemas/data_validation_failed"},{"$ref":"#/components/schemas/json_no_data"},{"$ref":"#/components/schemas/json_invalid_format"},{"$ref":"#/components/schemas/ndjson_no_data"},{"$ref":"#/components/schemas/ndjson_invalid_format"},{"$ref":"#/components/schemas/csv_invalid_row"},{"$ref":"#/components/schemas/csv_invalid_header"},{"$ref":"#/components/schemas/csv_no_data"},{"$ref":"#/components/schemas/csv_invalid_format"},{"$ref":"#/components/schemas/start_date_invalid"},{"$ref":"#/components/schemas/end_date_invalid"},{"$ref":"#/components/schemas/duplicate_rows"},{"$ref":"#/components/schemas/no_data"},{"$ref":"#/components/schemas/weekly_demand_date_check_failed"},{"$ref":"#/components/schemas/below_minimum_threshold"},{"$ref":"#/components/schemas/constant_demand_column"},{"$ref":"#/components/schemas/exceeding_missing_data_percentage"},{"$ref":"#/components/schemas/exceeding_consecutive_missing_data_volume"},{"$ref":"#/components/schemas/high_variance_difference_rate"},{"$ref":"#/components/schemas/unexpected_error"}]},"content_type_invalid":{"description":"The `Content-Type` header is unsupported.","type":"object","properties":{"code":{"description":"The error code identifying the type of error.","type":"string"},"message":{"description":"A human-readable error message describing the problem.","type":"string"}}},"data_validation_failed":{"description":"The format of the data uploaded is incorrect.","type":"object","properties":{"code":{"description":"The error code identifying the type of error.","type":"string"},"message":{"description":"A human-readable error message describing the problem.","type":"string"}}},"json_no_data":{"description":"An empty JSON body was uploaded.","type":"object","properties":{"code":{"description":"The error code identifying the type of error.","type":"string"},"message":{"description":"A human-readable error message describing the problem.","type":"string"}}},"json_invalid_format":{"description":"The uploaded JSON is formatted incorrectly. Please ensure JSON data is correctly UTF-8 encoded and that there are no invalid escape sequences.","type":"object","properties":{"code":{"description":"The error code identifying the type of error.","type":"string"},"message":{"description":"A human-readable error message describing the problem.","type":"string"}}},"ndjson_no_data":{"description":"An empty NDJSON body was uploaded.","type":"object","properties":{"code":{"description":"The error code identifying the type of error.","type":"string"},"message":{"description":"A human-readable error message describing the problem.","type":"string"}}},"ndjson_invalid_format":{"description":"The NDJSON body is formatted incorrectly. Please ensure NDJSON data is correctly UTF-8 encoded and that there are no invalid escape sequences.","type":"object","properties":{"code":{"description":"The error code identifying the type of error.","type":"string"},"message":{"description":"A human-readable error message describing the problem.","type":"string"}}},"csv_invalid_row":{"description":"The uploaded CSV has an invalid row.","type":"object","properties":{"code":{"description":"The error code identifying the type of error.","type":"string"},"message":{"description":"A human-readable error message describing the problem.","type":"string"}}},"csv_invalid_header":{"description":"The uploaded CSV headers are incorrect. Please use `date,demand`.","type":"object","properties":{"code":{"description":"The error code identifying the type of error.","type":"string"},"message":{"description":"A human-readable error message describing the problem.","type":"string"}}},"csv_no_data":{"description":"The uploaded CSV is empty or only has headers set.","type":"object","properties":{"code":{"description":"The error code identifying the type of error.","type":"string"},"message":{"description":"A human-readable error message describing the problem.","type":"string"}}},"csv_invalid_format":{"description":"The uploaded CSV is formatted incorrectly. Please ensure CSV data is correctly UTF-8 encoded and that there are no invalid escape sequences.","type":"object","properties":{"code":{"description":"The error code identifying the type of error.","type":"string"},"message":{"description":"A human-readable error message describing the problem.","type":"string"}}},"start_date_invalid":{"description":"The earliest date in the uploaded demand data is before `2017-01-01`.","type":"object","properties":{"code":{"description":"The error code identifying the type of error.","type":"string"},"message":{"description":"A human-readable error message describing the problem.","type":"string"}}},"end_date_invalid":{"description":"The latest date in the uploaded demand data is more than 1 year into the future.","type":"object","properties":{"code":{"description":"The error code identifying the type of error.","type":"string"},"message":{"description":"A human-readable error message describing the problem.","type":"string"}}},"duplicate_rows":{"description":"The uploaded demand data contains duplicate dates. Please remove all duplicates before uploading.","type":"object","properties":{"code":{"description":"The error code identifying the type of error.","type":"string"},"message":{"description":"A human-readable error message describing the problem.","type":"string"}}},"no_data":{"description":"There is no demand data.","type":"object","properties":{"code":{"description":"The error code identifying the type of error.","type":"string"},"message":{"description":"A human-readable error message describing the problem.","type":"string"}}},"weekly_demand_date_check_failed":{"description":"The weekly demand dates do not start on the same weekday.","type":"object","properties":{"code":{"description":"The error code identifying the type of error.","type":"string"},"message":{"description":"A human-readable error message describing the problem.","type":"string"}}},"below_minimum_threshold":{"description":"There are not enough data points in the uploaded demand data.","type":"object","properties":{"code":{"description":"The error code identifying the type of error.","type":"string"},"message":{"description":"A human-readable error message describing the problem.","type":"string"}}},"constant_demand_column":{"description":"The demand column is constant.","type":"object","properties":{"code":{"description":"The error code identifying the type of error.","type":"string"},"message":{"description":"A human-readable error message describing the problem.","type":"string"}}},"exceeding_missing_data_percentage":{"description":"There are too many missing demand values.","type":"object","properties":{"code":{"description":"The error code identifying the type of error.","type":"string"},"message":{"description":"A human-readable error message describing the problem.","type":"string"}}},"exceeding_consecutive_missing_data_volume":{"description":"There are too many consecutive missing demand values.","type":"object","properties":{"code":{"description":"The error code identifying the type of error.","type":"string"},"message":{"description":"A human-readable error message describing the problem.","type":"string"}}},"high_variance_difference_rate":{"description":"The variance of the uploaded demand data is too large to be processed.","type":"object","properties":{"code":{"description":"The error code identifying the type of error.","type":"string"},"message":{"description":"A human-readable error message describing the problem.","type":"string"}}},"unexpected_error":{"description":"An unexpected error occurred.","type":"object","properties":{"code":{"description":"The error code identifying the type of error.","type":"string"},"message":{"description":"A human-readable error message describing the problem.","type":"string"}}}}},"paths":{"/v1/beam/analyses/{analysis_id}/sink":{"post":{"operationId":"upload_analysis_demand","summary":"Upload Demand Data","description":"Beam Analyses support daily or weekly demand data. The type of data is detected automatically on upload.\n\nFor **daily** demand the minimum amount of data required is **6 months**, or 180 data points. Beam can impute up \nto 20% of missing values, provided that the minimum data requirements are satisfied and there are no more than 7 \nconsecutive days missing.\n\nFor **weekly** demand the minimum amount of data required is **2 years**, or 104 data points. Beam can impute up \nto 10% of missing values, provided that the minimum data requirements are satisfied and there are no more than 5 \nconsecutive weeks missing. All weekly data points must align with the **start of the week** and occur on the \nsame weekday.\n\nAll data points need to be between 2017-01-01 and one year into the future from today's date (today + 365 days).\n\nUploading data replaces existing data for the same date. It's not currently possible to remove data for a \nparticular date. The idea with this endpoint is that you're continuously adding new demand data over time.\n\nThe data can be uploaded in chunks, but the analysis data must remain valid at all times. If a newly uploaded \nchunk renders the analysis data invalid (for example, by introducing a large gap between data points), the \nchunk will be rejected, and the previously stored demand data will be preserved.","parameters":[{"name":"analysis_id","in":"path","description":"An existing Beam Analysis ID.","required":true,"schema":{"type":"string"}},{"name":"Content-Type","in":"header","description":"Content type of the uploaded payload.\n\n- `text/csv` — CSV format with `date` and `demand` columns.\n- `application/x-ndjson` — newline-delimited JSON, one `{\"date\": ..., \"demand\": ...}` object per line.\n- `application/json` — a JSON array of `{\"date\": ..., \"demand\": ...}` objects.\n- `application/x-ldjson` — deprecated, please use `application/x-ndjson`.","required":true,"schema":{"type":"string","enum":["text/csv","application/x-ndjson","application/json","application/x-ldjson"]}}],"requestBody":{"$ref":"#/components/requestBodies/UploadDemandData"},"responses":{"202":{"description":"Successful Response"},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/HTTPError"},{"$ref":"#/components/schemas/UploadErrorResponse"}]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}}}},"403":{"description":"Bearer token scope insufficient","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}}}},"404":{"description":"Analysis not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}}}},"409":{"description":"Data conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}}}}},"tags":["Analyses"]}}}}
```

## Error Codes

An unsuccessful HTTP response code could be returned for several reasons. In addition to an error message, there may also be a `code` field when applicable. The table below outlines the meaning of several error codes that may be returned.

| Code                                        | Description                                                                                                                                    |
| ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `content_type_invalid`                      | The `Content-Type` header is unsupported.                                                                                                      |
| `data_validation_failed`                    | The format of the data uploaded is incorrect.                                                                                                  |
| `json_no_data`                              | An empty JSON body was uploaded.                                                                                                               |
| `json_invalid_format`                       | The uploaded JSON is formatted incorrectly. Please ensure JSON data is correctly UTF-8 encoded and that there are no invalid escape sequences. |
| `ndjson_no_data`                            | An empty NDJSON body was uploaded.                                                                                                             |
| `ndjson_invalid_format`                     | The NDJSON body is formatted incorrectly. Please ensure NDJSON data is correctly UTF-8 encoded and that there are no invalid escape sequences. |
| `csv_invalid_row`                           | The uploaded CSV has an invalid row.                                                                                                           |
| `csv_invalid_header`                        | The uploaded CSV headers are incorrect. Please use `date,demand`.                                                                              |
| `csv_no_data`                               | The uploaded CSV is empty or only has headers set.                                                                                             |
| `csv_invalid_format`                        | The uploaded CSV is formatted incorrectly. Please ensure CSV data is correctly UTF-8 encoded and that there are no invalid escape sequences.   |
| `start_date_invalid`                        | The earliest date in the uploaded demand data is before `2017-01-01`.                                                                          |
| `end_date_invalid`                          | The latest date in the uploaded demand data is more than 1 year into the future.                                                               |
| `duplicate_rows`                            | The uploaded demand data contains duplicate dates. Please remove all duplicates before uploading.                                              |
| `no_data`                                   | There is no demand data.                                                                                                                       |
| `weekly_demand_date_check_failed`           | The weekly demand dates do not start on the same weekday.                                                                                      |
| `below_minimum_threshold`                   | There are not enough data points in the uploaded demand data.                                                                                  |
| `constant_demand_column`                    | The demand column is constant.                                                                                                                 |
| `exceeding_missing_data_percentage`         | There are too many missing demand values.                                                                                                      |
| `exceeding_consecutive_missing_data_volume` | There are too many consecutive missing demand values.                                                                                          |
| `high_variance_difference_rate`             | The variance of the uploaded demand data is too large to be processed.                                                                         |
| `unexpected_error`                          | An unexpected error occurred.                                                                                                                  |

## Examples

{% tabs %}
{% tab title="curl" %}

```bash
curl -X POST "https://api.predicthq.com/v1/beam/analyses/$ANALYSIS_ID/sink" \
     -H "Content-Type: text/csv" \
     -H "Authorization: Bearer $API_TOKEN" \
     --data @data.csv
```

{% endtab %}

{% tab title="python" %}

```python
import requests

response = requests.post(
    url="https://api.predicthq.com/v1/beam/analyses/$ANALYSIS_ID/sink",
    headers={
        "Authorization": "Bearer $API_TOKEN",
        "Content-Type": "text/csv"
    },
    data=open("data.csv")
)

print(response.status_code)
```

{% endtab %}
{% endtabs %}

## OpenAPI Spec

The OpenAPI spec for Beam API can be [found here](https://api.predicthq.com/docs/?urls.primaryName=Beam+API).

## Guides

Below are some guides relevant to this API:

* [Beam Guides](/getting-started/guides/beam-guides.md)


---

# Agent Instructions: 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.predicthq.com/api/beam/analyses/upload-demand-data.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.
