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

# Get the derivation graph around an attribute.

> Return the part of the derivation graph reachable from the given attribute: the attributes it can be derived
from, the attributes that can be derived from it, the rules connecting them, and the routes out of the
attribute with their total cost and fidelity. Only active rules the caller may use are followed, and an
attribute the caller cannot view is left out along with the rules touching it.

Authentication is optional. Anonymous callers see rules shared with every company and attributes shared with
every company. A token that is present but invalid is rejected rather than falling back to the anonymous view.



## OpenAPI

````yaml https://docs-cdn.narrative.io/api-reference/main/openapi.json get /attributes/{attribute_name_or_id}/derivation-graph
openapi: 3.1.1
info:
  contact:
    email: support@narrative.io
    name: Narrative Support
    url: https://www.narrative.io
  termsOfService: https://www.narrative.io/legal/terms-of-service
  x-logo:
    url: >-
      https://cdn.narrative.io/images/company-logos/prod/narrative-logo-text-white.svg
    backgroundColor: rgb(9, 34, 166)
    altText: Narrative Logo
  description: >-
    The [Narrative Data Collaboration Platform](https://app.narrative.io) API is
    organized around REST. Our API has predictable resource-oriented URLs,
    accepts form-encoded request bodies, returns JSON-encoded responses, and
    uses standard HTTP response codes, authentication, and verbs.



    The current version is a pre-release beta.  It may result in unexpected
    behavior and there may be breaking changes in future releases up to the 1.0
    release.
  title: Narrative Data Collaboration Platform API
  version: 2.4.x
servers:
  - url: https://api-dev.narrative.io
  - url: https://api.narrative.io
security: []
tags:
  - name: Access Rules
    description: >-
      Access rules let data providers control who can purchase their data and
      the terms of purchase.


      The `access-rules` API allows you to manage access rules for your
      datasets.


      Related guides:
        - [What is an access rule?](https://kb.narrative.io/access-rules)
  - name: Agent Conversations
    description: >-
      Build LLM-driven workflows that can call MCP tools, ask the caller for
      input, and return structured answers.


      A conversation pins a model, a system prompt, and a tool catalog. Each run
      sends the model a user message (or

      a batch of tool outputs from a previously-paused run); the model decides
      whether to answer directly, call a

      server-side tool (resolved by the platform via Model Context Protocol), or
      call a client-side tool (which pauses

      the run with `requires_action` and waits for the caller to reply).


      Related guides:
        - [Agent Conversations Reference](https://docs.narrative.io/reference/architecture/agent-conversations)
        - [Error catalog](https://docs.narrative.io/reference/architecture/agent-conversations/errors/conversation-not-found)
  - name: MCP Connections
    description: >-
      Connect external (non-Narrative) MCP servers so agent runs can call their
      tools with the

      calling user's own OAuth authorization.


      A connection is created interactively: `POST /mcp-connections` runs OAuth
      discovery and

      Dynamic Client Registration against the server and returns a consent URL;
      the user authorizes

      in a browser; the authorization server redirects to `GET
      /mcp-connections/callback`, which

      stores the authorization code and sends the browser on to the Narrative
      app; the app calls

      `POST /mcp-connections/complete` with the user's own bearer token, which
      exchanges the code and

      marks the connection `connected`.


      That last step is authenticated on purpose. The callback is public — it's
      a cross-site browser

      redirect, so no bearer reaches it — so it is not allowed to complete
      anything. Only the user

      who started the flow can turn the stored code into a token.


      Tokens are stored encrypted and used server-side — they are never returned
      by the API. Once

      connected, reference the connection by id from an agent run's
      `mcp_servers[].connection_id`.
  - name: App Invites
    description: >-
      App invites allow applications to create one-time, shareable links on
      behalf of their users. These links

      enable users to invite third parties who do not have a Narrative account
      to perform actions within the

      application.


      For example, a Narrative user can send an invite link to a third party who
      then completes a Pinterest

      OAuth flow and creates a connector profile in the inviter's account,
      allowing the inviter to deliver

      audience data to the third party's Pinterest account without the third
      party needing a Narrative account.


      This API is intended to be used by applications (via app client
      credentials) to create and manage invites

      on behalf of their users, which can then be shared with invitees.
  - name: Apps
    description: >-
      Apps are applications bundled with a UI that can perform various actions
      on behalf of a user utilizing the Narrative API.

      Related guides:
        - [Building a Narrative Native App](https://www.narrative.io/knowledge-base/how-to-guides/building-a-narrative-native-app)
  - name: Access Tokens
    description: >-
      System Access Tokens are long-lived bearer credentials for calling the API
      without a user present.


      A token belongs to a company, carries an explicit list of permissions, and
      expires on a date you choose — at

      least a day out and at most a year. `admin` access cannot be granted to
      one.


      `POST /access-tokens/tokens` is the only endpoint that returns the
      credential. Everything after that works in

      terms of the token's id: the list, get and update responses describe a
      token without ever repeating its

      `access_token`. If you lose it, delete the token and create another.


      Related guides:
        - [How to Create an API Token](https://www.narrative.io/knowledge-base/how-to-guides/understanding-narratives-apis/create-an-api-token)
  - name: Attributes
    description: >-
      An attribute models a standardized data point available for sale on the
      Narrative marketplace.


      Narrative automatically turns data points from provider datasets into
      attributes so that buyers can purchase well-formed, standardized data from
      any supplier on the marketplace.
  - name: Auth
    description: >-
      API token is a crucial step for developers to securely authenticate
      requests to the Narrative API

      Related guides:
        - [How to Create an API Token](https://www.narrative.io/knowledge-base/how-to-guides/understanding-narratives-apis/create-an-api-token)
  - name: Authentication
    description: User login and registration
  - name: Billings
    description: Used by Narrative internally to bill customers
  - name: Companies
    description: A collection of employees
  - name: Company Marketing Information
    description: Useful information related to companies
  - name: Compute Pools
    description: >-
      Compute pools represent compute resources (e.g. Snowflake warehouses)
      provisioned within a data plane.

      Companies can manage and share compute pools, assign them to jobs, and set
      a default compute pool on data planes.
  - name: Connections
    description: Associations between connectors and datasets
  - name: Data Shops
    description: |-
      Self-hosted website to sell your data
      Related guides:
        - [Setting up your datashop](https://www.narrative.io/knowledge-base/how-to-guides/shop-builder/settting-up-your-data-shop)
  - name: Data Streams
    description: >-
      The `data-stream` API endpoints allows one to create and update
      data-streams. Additionally the endpoints allow

      finding data-streams using free text search. A few of the endpoints are
      behind authorization.


      Update endpoint allows a client to post an edited data-stream document as
      is, without having to change its shape.

      The API ensures that only certain fields are allowed to be modified.
      Attempts to modify fields not up for client

      modifications are ignored.


      Related guides:
        - [What is a data stream?](https://kb.narrative.io/what-is-a-data-stream)
  - name: Contracts
    description: Contracts related APIs
  - name: Datasets
    description: >-
      Any kind of data, in any schema, can be pushed into the Narrative Data
      Collaboration Platform as a dataset exactly as it is stored in your own
      system.


      The `datasets` API allows you to manage your datasets.
  - name: Derivations
    description: >-
      Derivation rules describe how the value of one Rosetta Stone attribute can
      be computed from another — for

      example, hashing a raw email into a SHA-256 hashed email. Each rule
      carries a transformation expression that

      reads the source attribute's value through `$source`.


      The `derivations` API allows you to browse the rules your company can use
      — the ones it owns plus the ones

      shared with it through collaborators. Creating and changing them requires
      an `admin` grant on

      `attribute_derivations`, and a rule can only be changed by the company
      that owns it.
  - name: Destinations
    description: >-
      Destinations associate a subscription to a profile. Optionally, ad-hoc
      quick settings can be configured to a destination.

      Those quick settings have to match the format defined on the app manifest.
  - name: Installations
    description: Installations of Applications for a profile
  - name: Jobs
    description: >-
      Jobs represent an operation done on a given data plane. All jobs today are
      tied to a query that represents a forecast or a materialized view.


      The jobs API provides an interface for interacting with the jobs table,
      which stores various operations involving reading or writing data. This
      API allows users to retrieve detailed information about specific jobs,
      including NQL forecasts and materialized views.
  - name: Mappings
    description: >-
      A mapping is a transformation from a dataset to an attribute. Defining a
      mapping between a dataset and an attribute makes the dataset eligible to
      participate in subscriptions where a buyer is purchasing the target
      attribute.
  - name: Model Inference
    description: Model Inference
  - name: Model Training
    description: >-
      Train machine learning models on datasets, e.g. text classifiers used to
      power attribute mappings.
  - name: Models
    description: >-
      Machine learning models for training and inference.


      Models can be stored in HuggingFace or Narrative repositories and have
      configurable

      collaborator permissions for training and inference access.


      The `models` API allows you to list, retrieve, and update models
      accessible to your company.
  - name: NQL
    description: >-
      Narrative Query Language (NQL) is a specialized, SQL-inspired language
      designed to query and manipulate data within the Narrative platform. While
      it looks and feels much like standard SQL, it offers extended
      functionality and syntax that let you leverage platform-specific
      features—such as referencing datasets by their IDs, creating materialized
      views, or generating forecasts—without having to manage the complexities
      of different query engines behind the scenes. NQL queries can ultimately
      compile down to multiple underlying engines (e.g., Snowflake, Spark) to
      execute your requests efficiently in the Narrative ecosystem.
  - name: Payment Methods
    description: Payment methods used to purchase data
  - name: Products
    description: Internal routes used to offer datastream as products
  - name: Profiles
    description: >-
      App profiles are associated with an installation. They represent a
      reference to a configuration that the app can use to save confidential
      information outside of Narrative's control.

      Profiles are currently used to configure settings for connector apps.
  - name: Resources
    description: >-
      Narrative gives you access to managed resources, like your own AWS S3
      bucket, so that you can effortlessly buy and sell data on the platform.


      The `resources` API allows you to manage your resources.
  - name: Schema Inference
    description: >-
      The `schema-inference` API analyzes submitted files to automatically infer
      and return their structure as a dataset schema.
  - name: Schema Presets
    description: >-
      The `schema-presets` API allows you to list the available schema presets,
      get detailed information about a specific one and manage its life cycle.


      You can create a schema preset from scratch or create one based on an
      existing one, administrators can create platform wide available (public)
      schema preset.
  - name: Subscriptions
    description: >-
      In the Narrative Data Collaboration Platform a subscription represents a
      set of rules dictating the commercial terms related to the licensing of
      data.


      The `subscriptions` API allows you to set and get information about
      `subscription` objects owned by the authenticated account.
  - name: Uploads
    description: >-
      The `uploads` API allows you to send files to Narrative and use them to
      perform tasks like creating a list or adding data to a dataset.
  - name: Usage
    description: >-
      The `usage` API enables the recording of usage events associated with a
      product.
  - name: Webhooks
    description: >-
      Webhooks push events to a URL you control instead of making you poll for
      them.


      You create a subscription with the endpoint you want events sent to and a
      filter describing which events you

      want. Two kinds of subscription exist: job subscriptions follow the
      lifecycle of Narrative jobs, and app

      subscriptions follow the events a Narrative app reports through `POST
      /apps/events`.


      Creating a subscription returns a `secret`. Narrative sends it back in the
      `X-Narrative-Secret` header on

      every delivery, and comparing the two is how you tell a real callback from
      a forged one — so store it and do

      not share it.


      Deliveries are described under the "Event delivery" webhook below. Return
      any 2xx; anything else is retried

      with exponential backoff, and because a retry reuses the envelope's `id`,
      handlers should be idempotent

      on it.
  - name: Workflows
    description: >-
      The `workflows` API allows you to create, schedule, trigger, and archive
      workflows.

      Workflows are defined using a serverlessworkflow YAML specification.
paths:
  /attributes/{attribute_name_or_id}/derivation-graph:
    get:
      tags:
        - Attributes
      summary: Get the derivation graph around an attribute.
      description: >-
        Return the part of the derivation graph reachable from the given
        attribute: the attributes it can be derived

        from, the attributes that can be derived from it, the rules connecting
        them, and the routes out of the

        attribute with their total cost and fidelity. Only active rules the
        caller may use are followed, and an

        attribute the caller cannot view is left out along with the rules
        touching it.


        Authentication is optional. Anonymous callers see rules shared with
        every company and attributes shared with

        every company. A token that is present but invalid is rejected rather
        than falling back to the anonymous view.
      parameters:
        - $ref: '#/components/parameters/AttributeNameOrId'
        - $ref: '#/components/parameters/DerivationDirection'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AttributeDerivationGraphResponse'
        '400':
          description: '`direction` is not one of `descendants`, `ancestors`, `both`.'
        '401':
          description: >-
            The bearer token is expired or does not grant read access to
            attributes.
        '403':
          description: The bearer token could not be parsed or resolved.
        '404':
          description: No attribute with the given name or id is visible to the caller.
      security:
        - {}
        - BearerAuth: []
components:
  parameters:
    AttributeNameOrId:
      in: path
      name: attribute_name_or_id
      required: true
      description: Either an attribute name or an attribute id
      schema:
        oneOf:
          - type: integer
            description: Unique identifier
          - type: string
            description: Unique name
    DerivationDirection:
      in: query
      name: direction
      required: false
      description: >-
        Which way to walk from the attribute. `descendants` follows rules from
        source to target and reaches what can

        be derived from the attribute; `ancestors` follows them from target to
        source and reaches what the attribute

        can be derived from. The default walks both ways.
      schema:
        type: string
        enum:
          - descendants
          - ancestors
          - both
        default: both
  schemas:
    AttributeDerivationGraphResponse:
      type: object
      description: >-
        The part of the derivation graph reachable from one attribute through
        active rules the caller may use, over

        attributes the caller can view. `nodes` and `edges` are flat lists
        rather than a nested tree because the graph can

        contain cycles (a rule from birthdate to age and one from age to
        birthdate are both legitimate). A program walks

        the adjacency through `edges`; a person reads `paths`.


        The walk goes as far as query resolution can chain rules, which is one
        rule today, so every path listed is one a

        query can use. At most 50 paths are returned, descendants before
        ancestors.
      required:
        - attribute_id
        - attribute_name
        - direction
        - edges
        - nodes
        - paths
      properties:
        attribute_id:
          type: integer
          format: int64
        attribute_name:
          $ref: '#/components/schemas/AttributeName'
        direction:
          type: string
          enum:
            - descendants
            - ancestors
            - both
          description: The direction the walk followed, as requested.
        edges:
          type: array
          description: Every rule connecting two of the nodes, in rule id order.
          items:
            $ref: '#/components/schemas/AttributeDerivationEdge'
        nodes:
          type: array
          description: >-
            The requested attribute first, then the rest by distance and then by
            id.
          items:
            $ref: '#/components/schemas/AttributeDerivationGraphNode'
        paths:
          type: array
          items:
            $ref: '#/components/schemas/AttributeDerivationPath'
      example:
        attribute_id: 291
        attribute_name: normalized_email
        direction: both
        edges:
          - source:
              id: 118
              name: raw_email
            target:
              id: 291
              name: normalized_email
            derivation:
              id: 1
              name: raw_email_to_normalized_email
              description: >-
                Lower-cases the address and strips dots and plus-tags where the
                provider ignores them.
              cost: 1
              lossy: true
              imprecise: false
              fidelity_note: Normalization cannot be undone.
          - source:
              id: 291
              name: normalized_email
            target:
              id: 76
              name: sha256_hashed_email
            derivation:
              id: 2
              name: normalized_email_to_sha256_hashed_email
              description: Hashes the normalized address with SHA-256.
              cost: 1
              lossy: true
              imprecise: false
        nodes:
          - id: 291
            display_name: Normalized Email
            distance: 0
            name: normalized_email
            relationship: self
          - id: 76
            display_name: SHA-256 Hashed Email
            distance: 1
            name: sha256_hashed_email
            relationship: descendant
          - id: 118
            display_name: Raw Email
            distance: 1
            name: raw_email
            relationship: ancestor
        paths:
          - imprecise: false
            lossy: true
            relationship: descendant
            steps:
              - attribute_id: 76
                attribute_name: sha256_hashed_email
                derivation_id: 2
            total_cost: 1
          - imprecise: false
            lossy: true
            relationship: ancestor
            steps:
              - attribute_id: 118
                attribute_name: raw_email
                derivation_id: 1
            total_cost: 1
    AttributeName:
      type: string
      description: >-
        An short identifier for the attribute to be used when it is referenced
        in validations.


        Attribute names must consist of only alphanumeric characters or
        underscores and be < 255 characters long.
    AttributeDerivationEdge:
      type: object
      description: >-
        One derivation rule as an edge of the derivation graph: the attribute at
        each end and the rule connecting them.

        Both ends carry their name so no second lookup is needed to tell
        `raw_email` from `sha256_email`. The full rule,

        including its transformation, is available from `GET /derivations/{id}`.
      required:
        - source
        - target
        - derivation
      properties:
        source:
          allOf:
            - $ref: '#/components/schemas/AttributeDerivationEdgeEnd'
          description: The attribute the rule reads from.
        target:
          allOf:
            - $ref: '#/components/schemas/AttributeDerivationEdgeEnd'
          description: The attribute whose value the rule produces.
        derivation:
          $ref: '#/components/schemas/AttributeDerivationEdgeDerivation'
      example:
        source:
          id: 118
          name: raw_email
        target:
          id: 76
          name: sha256_email
        derivation:
          id: 42
          name: raw_email_to_sha256
          description: Hashes the raw email address with SHA-256.
          cost: 1
          lossy: true
          imprecise: false
          fidelity_note: Hashing is one-way, so the original address cannot be recovered.
    AttributeDerivationGraphNode:
      type: object
      description: An attribute the walk reached, including the requested attribute itself.
      required:
        - id
        - display_name
        - distance
        - name
        - relationship
      properties:
        id:
          type: integer
          format: int64
        display_name:
          $ref: '#/components/schemas/AttributeDisplayName'
        distance:
          type: integer
          minimum: 0
          description: >-
            Rules between this attribute and the requested one along the
            shortest route; 0 for the requested attribute.
        name:
          $ref: '#/components/schemas/AttributeName'
        relationship:
          type: string
          enum:
            - self
            - descendant
            - ancestor
            - both
          description: >-
            How the attribute relates to the requested one. `descendant`: it can
            be derived from the requested attribute.

            `ancestor`: the requested attribute can be derived from it. `both`:
            reachable either way, which only a cycle

            makes possible. `self`: the requested attribute.
    AttributeDerivationPath:
      type: object
      description: >-
        One route out of the requested attribute, one rule per step, visiting no
        attribute twice. Routes are reported

        once they cannot be extended, so every shorter route is a prefix of one
        listed here.
      required:
        - imprecise
        - lossy
        - relationship
        - steps
        - total_cost
      properties:
        imprecise:
          type: boolean
          description: Set when any rule on the route is imprecise.
        lossy:
          type: boolean
          description: Set when any rule on the route is lossy.
        relationship:
          type: string
          enum:
            - descendant
            - ancestor
          description: Which way the route goes from the requested attribute.
        steps:
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/AttributeDerivationPathStep'
        total_cost:
          type: integer
          minimum: 1
          description: The sum of the cost of every rule on the route.
    AttributeDerivationEdgeEnd:
      type: object
      description: The attribute at one end of an edge.
      required:
        - id
        - name
      properties:
        id:
          type: integer
          format: int64
        name:
          $ref: '#/components/schemas/AttributeName'
    AttributeDerivationEdgeDerivation:
      type: object
      description: The rule on an edge, without its transformation.
      required:
        - id
        - name
        - description
        - cost
        - lossy
        - imprecise
      properties:
        id:
          $ref: '#/components/schemas/DerivationId'
        name:
          $ref: '#/components/schemas/DerivationName'
        description:
          $ref: '#/components/schemas/DerivationDescription'
        cost:
          $ref: '#/components/schemas/DerivationCost'
        lossy:
          type: boolean
          description: The transformation loses information, e.g. hashing.
        imprecise:
          type: boolean
          description: >-
            The transformation is approximate, e.g. bucketing an age into a
            range.
        fidelity_note:
          allOf:
            - $ref: '#/components/schemas/FidelityNote'
          description: >-
            Explains the `lossy` and `imprecise` flags to whoever is deciding
            whether to accept derived data. Omitted

            when the rule has no note.
    AttributeDisplayName:
      type: string
      description: A public-facing descriptive name for the attribute.
    AttributeDerivationPathStep:
      type: object
      description: >-
        One rule taken along a path and the attribute it leads to: the rule's
        target when walking towards descendants,

        its source when walking towards ancestors.
      required:
        - attribute_id
        - attribute_name
        - derivation_id
      properties:
        attribute_id:
          type: integer
          format: int64
        attribute_name:
          $ref: '#/components/schemas/AttributeName'
        derivation_id:
          $ref: '#/components/schemas/DerivationId'
    DerivationId:
      type: integer
      format: int64
      description: Unique identifier of the derivation rule.
      example: 42
    DerivationName:
      type: string
      maxLength: 256
      description: Name of the derivation rule, unique within the owning company.
      example: raw_email_to_sha256
    DerivationDescription:
      type: string
      maxLength: 2048
      description: >-
        What the rule does, for whoever is deciding whether to accept derived
        data.
      example: Hashes the raw email address with SHA-256.
    DerivationCost:
      type: integer
      minimum: 1
      default: 1
      description: >-
        Breaks ties when more than one rule reaches the same target attribute —
        cheapest first. Resolution over multi-step

        paths sums the cost of every rule on a path and prefers the cheapest
        total.
    FidelityNote:
      type: string
      maxLength: 2048
      description: >-
        Explains the `lossy` and `imprecise` flags to whoever is deciding
        whether to accept derived data.
      example: Hashing is one-way, so the original address cannot be recovered.
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer

````