# Create or update an information stream

**Requires scope:** `forecasting`.
Create or update the metadata for an information stream.
**Important notes:**
- When updating an existing information stream, include all keys to avoid unintentionally resetting values to their defaults.
- `departmentIds` is optional. It may contain department, department group, or location IDs. A department group or location is automatically expanded to its active child departments; the group or location ID itself is not linked. An explicitly listed department is always linked, even when archived. A non-empty selection that resolves to no active departments is rejected.
- The linked departments are stored as a snapshot at the moment of the request. Later changes to the organizational structure (for example adding a department to a group) do not change the departments already linked to an existing information stream.
- Department, department group, and location IDs can be looked up by fetching the department tree with [`GET /api/department-management/v3/tree`](#tag/Offices-and-departments/operation/getDepartmentTree). Fetching the department tree requires a token with the `business` scope; the `forecasting` scope alone does not grant access to it.
- On create, `departmentIds` may be omitted; the stream is then created without linked departments.
- On update, `departmentIds` is only applied when a non-empty list is provided. Omitting it (or sending an empty list) leaves the existing departments unchanged.
- `granularity` is required when creating a new information stream.
- When updating an existing information stream, `granularity` is optional. If provided, it must match the already configured granularity. Changing granularity through this endpoint is not supported.
- When onboarding a newly realized workload information stream, ensure that all historically realized data is fully inserted.

Endpoint: POST /information-streams/v3/streams
Security: apiKey

## Request fields (application/json):

  - `key` (string)
    The key of the existing information stream.
If no key parameter is given, Dyflexis will create a new information stream and return the generated stream key.
Only information streams with source `api` can be updated through this endpoint.
    Example: covers-per-hour-pier9

  - `type` (string, required)
    Type of the information stream.
    Enum: "workload", "staff"

  - `unit` (string)
    Unit of the information stream
If type is "workload": any string value is allowed. String value 'revenue' will automatically display the currency icon in Dyflexis.
If type is "staff": only types 'hours' or 'currency' are allowed.
    Example: covers

  - `category` (string, required)
    Category of the information stream
    Enum: "budget", "forecast", "realized"

  - `granularity` (string)
    Granularity of the information stream.
Required when creating a new information stream.
Optional when updating an existing information stream. If provided on update, it must match the existing granularity.
Changing granularity through this endpoint is not supported.
    Enum: "hour", "day", "week", "month", "quarter", "year"

  - `name` (string, required)
    Name of the information stream. Visible for users in Dyflexis.
    Example: Pier 9 covers per hour

  - `note` (string)
    Additional notes about the information stream.
    Example: Realised covers per hour at the Pier 9 Bistro, used to drive demand-based scheduling.

  - `departmentIds` (array)
    List of department, department group, or location IDs linked to the information stream. Optional.
A department group or location is automatically expanded to its active child departments; the group or location ID itself is not linked. An explicitly listed department is always linked, even when archived. A non-empty selection that resolves to no active departments is rejected.
The linked departments are stored as a snapshot at the moment of the request; later changes to the organizational structure do not change the departments already linked to an existing information stream.
On create, may be omitted to create a stream without linked departments.
On update, only applied when a non-empty list is provided; omitting it (or sending an empty list) leaves the existing departments unchanged.
Department, department group, and location IDs can be looked up by fetching the department tree with [`GET /api/department-management/v3/tree`](#tag/Offices-and-departments/operation/getDepartmentTree); this requires a token with the `business` scope.
Can also be configured manually in the frontend of the forecasting module in Dyflexis.
    Example: [1,2,3]

  - `isActive` (boolean, required)
    Indicates whether the information stream is visible for operations or not (if 'true', it will be visible for the performance dashboard, reporting, scheduling).
    Example: true

  - `sourceSystem` (string, required)
    Source system of the 3rd party tech provider.
    Example: Hospitality POS solutions

  - `sourceSystemSupportEmail` (string, required)
    Support email address of the tech partner.
    Example: techsupport@techpartner.com

## Response 201 fields (application/json):

  - `key` (string)
    The Dyflexis generated information stream key

## Response 400 fields (application/json):

  - `title` (string, required)
    Short, human-readable summary of the error.
    Example: Unauthorized

  - `status` (integer, required)
    The HTTP status code.
    Example: 401

  - `message` (string, required)
    Human-readable explanation of this occurrence of the error.
    Example: Invalid Token

  - `detail` (string)
    Human-readable explanation of this occurrence. Not returned by all backend versions.
    Example: Invalid Token

  - `code` (integer)
    The HTTP status code (duplicate of `status`). Not returned by all backend versions.
    Example: 401

  - `type` (string)
    URI reference identifying the error type, when present.
    Example: https://tools.ietf.org/html/rfc2616#section-10

  - `violations` (array)
    Per-field validation failures (one backend variant).

  - `violations.propertyPath` (string)
    Example: employeeId

  - `violations.title` (string)
    Example: This value should not be null.

  - `violations.type` (string | null)

  - `errors` (array)
    Per-field validation failures (another backend variant).

  - `errors.message` (string)
    Example: This value should not be null.

  - `errors.code` (string | null)
    Machine-readable violation code.

  - `errors.context` (object)

  - `errors.context.field` (string | null)

## Response 401 fields (application/json):

  - `title` (string, required)
    Short, human-readable summary of the error.
    Example: Unauthorized

  - `status` (integer, required)
    The HTTP status code.
    Example: 401

  - `message` (string, required)
    Human-readable explanation of this occurrence of the error.
    Example: Invalid Token

  - `detail` (string)
    Human-readable explanation of this occurrence. Not returned by all backend versions.
    Example: Invalid Token

  - `code` (integer)
    The HTTP status code (duplicate of `status`). Not returned by all backend versions.
    Example: 401

## Response 403 fields (application/json):

  - `title` (string, required)
    Short, human-readable summary of the error.
    Example: Unauthorized

  - `status` (integer, required)
    The HTTP status code.
    Example: 401

  - `message` (string, required)
    Human-readable explanation of this occurrence of the error.
    Example: Invalid Token

  - `detail` (string)
    Human-readable explanation of this occurrence. Not returned by all backend versions.
    Example: Invalid Token

  - `code` (integer)
    The HTTP status code (duplicate of `status`). Not returned by all backend versions.
    Example: 401

## Response 404 fields (application/json):

  - `title` (string, required)
    Short, human-readable summary of the error.
    Example: Unauthorized

  - `status` (integer, required)
    The HTTP status code.
    Example: 401

  - `message` (string, required)
    Human-readable explanation of this occurrence of the error.
    Example: Invalid Token

  - `detail` (string)
    Human-readable explanation of this occurrence. Not returned by all backend versions.
    Example: Invalid Token

  - `code` (integer)
    The HTTP status code (duplicate of `status`). Not returned by all backend versions.
    Example: 401

## Response 500 fields (application/json):

  - `title` (string, required)
    Short, human-readable summary of the error.
    Example: Unauthorized

  - `status` (integer, required)
    The HTTP status code.
    Example: 401

  - `message` (string, required)
    Human-readable explanation of this occurrence of the error.
    Example: Invalid Token

  - `detail` (string)
    Human-readable explanation of this occurrence. Not returned by all backend versions.
    Example: Invalid Token

  - `code` (integer)
    The HTTP status code (duplicate of `status`). Not returned by all backend versions.
    Example: 401

