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

# Create a data feed transformation

> Adds a transformation for an event type to a data feed. The event type must belong to the project. Parameters are sent at the top level of the JSON body, not nested.

Optionally send `script_content` and `description` to create the first transformation version in the same request; that requires the API token to be associated with a user (same rule as PATCH). Without a script, the feed reports it is not ready until one is added.

If the data feed already has an active transformation for the event type, none is created: a `script_content` that differs from the current script adds a new version to it, and the response is 200 instead of 201. Requires the `read:project` and `write:project` token scopes.




## OpenAPI

````yaml POST /projects/{project_id}/data_feeds/{data_feed_id}/transformations
openapi: 3.1.0
info:
  title: Mangrove - API
  version: 1.1.0
  description: >
    ## Filtering and sorting


    List endpoints that accept `filter` take one query parameter per condition,
    written `filter[field][comparator]=value`, for example
    `filter[name][contains]=North`. The comparators are `eq`, `neq`, `gt`,
    `geq`, `lt`, `leq` and `contains`, and `filter[field]=value` is short for
    `eq`. Conditions combine with AND. `contains` matches part of the value, is
    case-sensitive, and applies only to text fields. An unknown field or
    comparator, a value that doesn't fit the field's type, or a list or object
    as the value returns 400 with a message naming the problem. Each list
    operation names its filterable fields; some take only `eq`, and say so.


    `sort` takes a comma-separated list of fields, for example
    `sort=-created_at,name`. Each field sorts ascending, or descending with a
    `-` prefix. Unknown sort fields are ignored. Sorting by `id` orders by the
    record's internal ID, not its friendly ID. Each list operation names its
    sortable fields.
servers:
  - url: https://app.gomangrove.com/api/v1
security:
  - sec0: []
paths:
  /projects/{project_id}/data_feeds/{data_feed_id}/transformations:
    post:
      tags:
        - Data Ingestion
      summary: Create a data feed transformation
      description: >
        Adds a transformation for an event type to a data feed. The event type
        must belong to the project. Parameters are sent at the top level of the
        JSON body, not nested.


        Optionally send `script_content` and `description` to create the first
        transformation version in the same request; that requires the API token
        to be associated with a user (same rule as PATCH). Without a script, the
        feed reports it is not ready until one is added.


        If the data feed already has an active transformation for the event
        type, none is created: a `script_content` that differs from the current
        script adds a new version to it, and the response is 200 instead of 201.
        Requires the `read:project` and `write:project` token scopes.
      operationId: create-data-feed-transformation
      parameters:
        - $ref: '#/components/parameters/ProjectId'
        - $ref: '#/components/parameters/DataFeedId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - event_type_id
              properties:
                event_type_id:
                  type: string
                  description: >-
                    The friendly ID of an event type in the project (e.g.
                    `et_aBcD1234eFgH5678`).
                  example: et_aBcD1234eFgH5678
                script_content:
                  type:
                    - string
                    - 'null'
                  description: >
                    When set, creates a transformation version with this Python
                    script. Requires the API token to be associated with a user
                    (same as PATCH transformation).
                description:
                  type:
                    - string
                    - 'null'
                  description: >-
                    Optional note stored on the new transformation version when
                    script_content is provided, up to 500 characters
      responses:
        '200':
          description: The event type already had a transformation; returns the data feed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataFeed'
        '201':
          description: >-
            Transformation created; returns the data feed, including its
            transformations
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataFeed'
        '400':
          description: '`event_type_id` is missing'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                  - message: >-
                      param is missing or the value is empty or invalid:
                      event_type_id
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: Project, nexus config, data feed, or event type not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                projectNotFound:
                  value:
                    errors:
                      - message: Record not found
                noNexusConfig:
                  value:
                    errors:
                      - message: Project does not have data ingestion enabled
                dataFeedNotFound:
                  value:
                    errors:
                      - message: Pipeline not found
                eventTypeNotFound:
                  value:
                    errors:
                      - message: Event type not found
        '422':
          description: >-
            Validation error when persisting the transformation, or a
            `script_content` sent with a token not linked to a user
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                tokenWithoutUser:
                  value:
                    errors:
                      - message: >-
                          API token must be associated with a user for write
                          operations
components:
  parameters:
    ProjectId:
      name: project_id
      in: path
      required: true
      description: The project's friendly ID (e.g. `prj_aBcD1234eFgH5678`).
      schema:
        type: string
    DataFeedId:
      name: data_feed_id
      in: path
      required: true
      description: The data feed's friendly ID (e.g. `datafd_aBcD1234eFgH5678`).
      schema:
        type: string
  schemas:
    DataFeed:
      type: object
      description: >-
        A data feed. List rows omit each transformation's `script_content` and
        each source's `config`; single-feed responses include them.
      properties:
        id:
          type: string
          description: The data feed's friendly ID.
          example: datafd_aBcD1234eFgH5678
        name:
          type: string
          example: Daily Production Data
        description:
          type:
            - string
            - 'null'
          example: Imports daily production metrics
        headers_row_number:
          type: integer
          description: >-
            Row number (1-based) containing column headers. Rows above are
            ignored during ingestion. 1 until a schema sets another value.
          example: 1
        setup_error:
          type:
            - string
            - 'null'
          description: >-
            Why automatic setup could not build the schema (for example an
            unreadable sample file), or null.
        not_ready_message:
          type:
            - string
            - 'null'
          description: >-
            Why the feed cannot accept data yet, or null when it is ready. A new
            feed reports "Transformation scripts are still being generated"
            until its scripts are drafted, and "Schema not defined" until a
            schema exists.
          example: null
        schema_fields:
          type: array
          description: The columns of the current schema. Empty until a schema is defined.
          items:
            type: object
            properties:
              name:
                type: string
                example: site_name
              value_type:
                type: string
                enum:
                  - string
                  - number
                  - boolean
        event_types:
          type: array
          description: The event types the feed's active transformations create.
          items:
            type: object
            properties:
              id:
                type: integer
                description: >-
                  Numeric event type ID. Use `transformations[].event_type_id`
                  for the friendly ID.
              name:
                type: string
              slug:
                type: string
        transformations:
          type: array
          description: Active (unarchived) transformations, one per event type.
          items:
            type: object
            properties:
              id:
                type: string
                description: The transformation's friendly ID.
                example: tfn_aBcD1234eFgH5678
              event_type_id:
                type: string
                description: The event type's friendly ID.
                example: et_aBcD1234eFgH5678
              event_type_name:
                type: string
              script_status:
                type:
                  - string
                  - 'null'
                enum:
                  - generating
                  - ready
                  - failed
                  - null
                description: >-
                  Status of the automatically drafted script. null for a
                  transformation created without one.
              script_content:
                type:
                  - string
                  - 'null'
                description: >-
                  The latest script version, or null when there is none.
                  Single-feed responses only.
        sources:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
                description: The source's friendly ID.
                example: dsrc_aBcD1234eFgH5678
              name:
                type: string
              source_type:
                type: string
                enum:
                  - endpoint
                  - ui_upload
                  - sql
                  - api
              config:
                $ref: '#/components/schemas/DataFeedSourceConfigResponse'
        ui_url:
          type: string
          format: uri
          description: Link to the data feed's page in the app.
          example: >-
            https://app.gomangrove.com/nexus/prj_aBcD1234eFgH5678/data-inputs/data-feeds/datafd_aBcD1234eFgH5678
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    ErrorResponse:
      type: object
      required:
        - errors
      properties:
        errors:
          type: array
          items:
            type: object
            required:
              - message
            properties:
              message:
                type: string
                description: Human-readable error message
              field:
                type: string
                description: Attribute the error applies to (validation errors only)
              code:
                type: string
                description: Machine-readable error code (validation errors only)
              blocking:
                type: array
                description: >-
                  Bounded preview of the records blocking a destroy
                  (blocked-destroy errors only)
                items:
                  $ref: '#/components/schemas/DeletionBlockingRecord'
              blocking_count:
                type: integer
                description: >-
                  Total count of records blocking a destroy (blocked-destroy
                  errors only)
              config_key:
                type: string
                description: >-
                  The data feed source config setting to fix, when the error is
                  on `config` (data feed source validation errors only)
              count:
                type: number
                description: >-
                  The limit or comparison value the failed validation checked
                  against, e.g. a maximum length or a numeric bound (validation
                  errors only, when the validation has one)
              value:
                description: >-
                  The rejected value, e.g. on an inclusion or uniqueness failure
                  (validation errors only, when the validation reports one)
    DataFeedSourceConfigResponse:
      type: object
      description: >-
        The source's stored `config`, with the keys described for the request
        body. Scalar values are returned as strings, so `daily_fetch` reads
        `"true"` and a port `"1433"`; objects and arrays (`headers`, `query`,
        `auth`, `poll`, `success_when`) are returned as JSON. Credentials never
        appear here, but values typed directly into `headers` or `query` are
        stored and returned as entered.
      additionalProperties:
        oneOf:
          - type: string
          - type: object
            additionalProperties: true
          - type: array
            items: {}
    DeletionBlockingRecord:
      type: object
      required:
        - type
      properties:
        type:
          type: string
        friendly_id:
          type: string
        name:
          type:
            - string
            - 'null'
          description: >-
            Display label, and the only identifier for records that have no
            friendly_id
  responses:
    Unauthorized:
      description: >-
        The API token is missing, invalid or expired. The body is empty, except
        for an expired token, which returns the error below.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            errors:
              - message: API token has expired
    Forbidden:
      description: >-
        The token lacks the scope the operation's description names, or a
        condition the description states applies, such as a feature that isn't
        enabled for your account.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            errors:
              - message: You are not authorized to perform this action
  securitySchemes:
    sec0:
      type: apiKey
      in: header
      name: Authorization
      x-bearer-format: ''

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.