# Schema

## Overview

We provide auto-generated GraphQL schema documentation for both The Graph and Envio:

-   [The Graph schema docs](/api/streams/graphql/the-graph/overview)
-   [Envio schema docs](/api/streams/graphql/envio/overview)

## Query Syntax Differences

| Feature | The Graph | Envio |
| --- | --- | --- |
| Pagination | `first` | `limit` |
| Pagination | `skip` | `offset` |
| Get by ID | `lockupStream(id: "...")` / `flowStream(id: "...")` | `LockupStream_by_pk(id: "...")` / `FlowStream_by_pk(id: "...")` |
| Get multiple | `lockupStreams{}` / `flowStreams{}` | `LockupStream(where: {...}){}` / `FlowStream(where: {...}){}` |
| Nested items | `campaigns{ id, asset: {id, symbol}}` | `Campaign{ asset_id, asset: {id, symbol}}` |

## Entities

This is the raw GraphQL file that is used by both The Graph and Envio for generating the final schemas hosted on their services.

The schema only contains entities:

```graphql
enum FlowActionCategory {
  Approval
  ApprovalForAll
  Adjust
  Create
  Deposit
  Pause
  Refund
  Restart
  Transfer
  Void
  Withdraw
}

enum FlowStreamCategory {
  Flow
}

enum LockupActionCategory {
  Approval
  ApprovalForAll
  Cancel
  Create
  Renounce
  Transfer
  Withdraw
}

enum LockupStreamCategory {
  LockupDynamic
  LockupLinear
  LockupTranched
}

enum ShapeSource {
  Event
  Inferred
}

"""
ERC-20 asset
"""
type Asset @entity(immutable: false) {
  """
  Unique identifier: `asset-{chainId}-{address}`
  """
  id: String!
  """
  Address of the ERC-20 token.
  """
  address: Bytes!
  """
  The chain ID where the asset exists (e.g., 137 for Polygon).
  """
  chainId: BigInt!
  """
  Decimals of the ERC20 token.
  """
  decimals: BigInt!
  """
  Name of the ERC20 token.
  """
  name: String!
  """
  Symbol of the ERC20 token.
  """
  symbol: String!
  """
  Flow streams that rely on this token
  """
  flowStreams: [FlowStream!]! @derivedFrom(field: "asset")
  """
  Lockup streams that rely on this token
  """
  lockupStreams: [LockupStream!]! @derivedFrom(field: "asset")
}

type Watcher @entity(immutable: false) {
  """
  The chain ID. There is one watcher per subgraph.
  """
  id: String!
  """
  Alias for id.
  """
  chainId: BigInt!
  """
  Global counter for Flow actions.
  """
  flowActionCounter: BigInt!
  """
  Global counter for Flow streams.
  """
  flowStreamCounter: BigInt!
  """
  Global counter for Lockup actions.
  """
  lockupActionCounter: BigInt!
  """
  Global counter for Lockup streams.
  """
  lockupStreamCounter: BigInt!
}

type FlowStream @entity(immutable: false) {
  """
  Unique identifier: `{contractAddress}-{chainId}-{tokenId}`
  """
  id: String!
  """
  Like the id: `{contractAlias}-{chainId}-{tokenId}`
  """
  alias: String!
  """
  The chain ID where the stream was created (e.g., 137 for Polygon).
  """
  chainId: BigInt!
  """
  Unique global id as tracked by the `Watcher` entity.
  🚨 This may change if new data sources are added and the chronological order of streams changes.
  """
  subgraphId: BigInt!
  """
  The id provided by the NFT contract. It's the ERC-721 tokenId.
  """
  tokenId: BigInt!
  """
  Hash of the Ethereum transaction that created this stream.
  """
  hash: Bytes!
  """
  Unix timestamp of the Ethereum transaction that created this stream.
  """
  timestamp: BigInt!
  """
  Actions triggered by this stream.
  """
  actions: [FlowAction!]! @derivedFrom(field: "stream")
  """
  ERC-20 token distributed via this stream.
  """
  asset: Asset!
  """
  ERC-20 token decimals. Stored here to avoid loading the asset entity on each stream.
  Note: the "Value" suffix is added because of a bug in GraphQL Code Generator.
  """
  assetDecimalsValue: BigInt!
  """
  The batch the stream may be part of.
  Note: this is available only when created within a batch create transaction.
  """
  batch: FlowBatch!
  """
  Category used for sorting.
  """
  category: FlowStreamCategory!
  """
  The address of the contract the stream originates from.
  """
  contract: Bytes!
  """
  Position in the batch, if available.
  """
  position: BigInt!
  """
  Current recipient of the stream, with permission to withdraw funds to any third-party address.
  Note: the recipient can change on NFT transfer.
  """
  recipient: Bytes!
  """
  Manager of the stream, with ability to cancel the stream.
  """
  sender: Bytes!
  """
  Unix timestamp for the start of the stream.
  """
  startTime: BigInt!
  """
  Flag indicating the transferability of the stream. This is set when the stream is created, and cannot
  be changed later.
  """
  transferable: Boolean!
  """
  Version of contract, e.g., v1.0.
  """
  version: String!
  """
  The sum of all withdrawn amounts.
  """
  withdrawnAmount: BigInt!
  """
  This is equivalent to the value returned by ERC20.balanceOf, and it changes after deposit and withdrawal.
  """
  availableAmount: BigInt!
  """
  The account that created the stream, which can be different from the sender.
  """
  creator: Bytes!
  """
  Unix timestamp indicating the time when the stream will become insolvent.
  """
  depletionTime: BigInt!
  """
  The sum of all deposits.
  """
  depositedAmount: BigInt!
  """
  The amount of debt forgiven by a void action.
  """
  forgivenDebt: BigInt!
  """
  Action in which the payment rate was adjusted.
  """
  lastAdjustmentAction: FlowAction
  """
  Unix timestamp for when the payment rate was adjusted.
  """
  lastAdjustmentTimestamp: BigInt!
  """
  Flag indicating if a stream is paused.
  """
  paused: Boolean!
  """
  Action in which the stream was paused.
  """
  pausedAction: FlowAction
  """
  Unix timestamp for when the stream was paused.
  """
  pausedTime: BigInt
  """
  Current payment rate per second, denominated in 18 decimals.
  """
  ratePerSecond: BigInt!
  """
  The sum of all refunds.
  """
  refundedAmount: BigInt!
  """
  The amount streamed up until the time of the last adjustment, denominated in 18 decimals.
  """
  snapshotAmount: BigInt!
  """
  Flag indicating if a stream is voided.
  """
  voided: Boolean!
  """
  Action in which the stream was voided.
  """
  voidedAction: FlowAction
  """
  Unix timestamp for when the stream was voided.
  """
  voidedTime: BigInt
}

type LockupStream @entity(immutable: false) {
  """
  Unique identifier: `{contractAddress}-{chainId}-{tokenId}`
  """
  id: String!
  """
  Like the id: `{contractAlias}-{chainId}-{tokenId}`
  """
  alias: String!
  """
  The chain ID where the stream was created (e.g., 137 for Polygon).
  """
  chainId: BigInt!
  """
  Unique global id as tracked by the `Watcher` entity.
  🚨 This may change if new data sources are added and the chronological order of streams changes.
  """
  subgraphId: BigInt!
  """
  The id provided by the NFT contract. It's the ERC-721 tokenId.
  """
  tokenId: BigInt!
  """
  Hash of the Ethereum transaction that created this stream.
  """
  hash: Bytes!
  """
  Unix timestamp of the Ethereum transaction that created this stream.
  """
  timestamp: BigInt!
  """
  Actions triggered by this stream.
  """
  actions: [LockupAction!]! @derivedFrom(field: "stream")
  """
  ERC-20 token distributed via this stream.
  """
  asset: Asset!
  """
  ERC-20 token decimals. Stored here to avoid loading the asset entity on each stream.
  Note: the "Value" suffix is added because of a bug in GraphQL Code Generator.
  """
  assetDecimalsValue: BigInt!
  """
  The batch the stream may be part of.
  Note: this is available only when created within a batch create transaction.
  """
  batch: LockupBatch!
  """
  Category used for sorting.
  """
  category: LockupStreamCategory!
  """
  The address of the contract the stream originates from.
  """
  contract: Bytes!
  """
  Position in the batch, if available.
  """
  position: BigInt!
  """
  Current recipient of the stream, with permission to withdraw funds to any third-party address.
  Note: the recipient can change on NFT transfer.
  """
  recipient: Bytes!
  """
  Manager of the stream, with ability to cancel the stream.
  """
  sender: Bytes!
  """
  Unix timestamp for the start of the stream.
  """
  startTime: BigInt!
  """
  Flag indicating the transferability of the stream. This is set when the stream is created, and cannot
  be changed later.
  """
  transferable: Boolean!
  """
  Version of contract, e.g., v1.0.
  """
  version: String!
  """
  The sum of all withdrawn amounts.
  """
  withdrawnAmount: BigInt!
  """
  Action in which the stream was canceled.
  """
  canceledAction: LockupAction
  """
  Action in which the stream was made non-cancelable.
  Note: if the stream was made non-cancelable from the get-go, this is the same as the Create action.
  """
  renounceAction: LockupAction
  """
  Flag indicating the cancelability of the stream.
  """
  cancelable: Boolean!
  """
  Flag indicating if the stream was canceled.
  """
  canceled: Boolean!
  """
  Unix timestamp for the when the stream was canceled.
  """
  canceledTime: BigInt
  """
  The amount deposited when the stream was created.
  """
  depositAmount: BigInt!
  """
  Snapshot of the duration in seconds (the difference between end and start time).
  """
  duration: BigInt!
  """
  Unix timestamp for the end of the stream.
  """
  endTime: BigInt!
  """
  The account that funded the stream, which can be different from the sender.
  """
  funder: Bytes!
  """
  The amount that is still held by the stream regardless of whether if was fully vested or not.
  This is the difference between the deposit amount and all withdrawn amounts.
  """
  intactAmount: BigInt!
  """
  Flag indicating if the stream has been fully withdrawn (intactAmount is zero).
  """
  depleted: Boolean!
  """
  Owner of the proxy when the stream is created through a PRBProxy (https://github.com/PaulRBerg/prb-proxy)
  Note that proxy = stream sender, and proxender = owner of proxy
  """
  proxender: Bytes
  """
  Flag for streams created through a PRBProxy.
  """
  proxied: Boolean!
  """
  Unix timestamp for when the stream was made non-cancelable. This can coincide with the create time.
  """
  renounceTime: BigInt
  """
  An optional parameter to specify the shape of the distribution.
  Available since Lockup v2.0.
  """
  shape: String
  """
  The source of the shape value: Event (from contract event) or Inferred (computed by indexer).
  """
  shapeSource: ShapeSource
  """
  Flag for Linear streams with a cliff.
  """
  cliff: Boolean
  """
  The amount that will unlock at the cliff time.
  """
  cliffAmount: BigInt
  """
  Unix timestamp for the start of the cliff.
  """
  cliffTime: BigInt
  """
  The smallest step in time between two consecutive token unlocks.
  Applies only for LockupLinear and available since Lockup v4.0
  """
  granularity: BigInt
  """
  Flag for Linear stream with an initial unlock.
  Available since Lockup v2.0.
  """
  initial: Boolean
  """
  The initial unlock amount of a Linear stream.
  Available since Lockup v2.0.
  """
  initialAmount: BigInt
  """
  Segments of a Dynamic stream.
  """
  segments: [Segment!]! @derivedFrom(field: "stream")
  """
  Segments of a Tranched stream.
  """
  tranches: [Tranche!]! @derivedFrom(field: "stream")
}

"""
A generic entity for tracking Flow protocol actions.
"""
type FlowAction @entity(immutable: true) {
  """
  Unique identifier: `action-{chainId}-{txHash}-{logIndex}`
  """
  id: String!
  """
  Unique global id as tracked by the `Watcher` entity.
  """
  subgraphId: BigInt!
  """
  Block number of the Ethereum transaction.
  """
  block: BigInt!
  """
  The chain ID where the action was created (e.g., 137 for Polygon).
  """
  chainId: BigInt!
  """
  The tx.origin of the Ethereum transaction.
  """
  from: Bytes!
  """
  Hash of the Ethereum transaction.
  """
  hash: Bytes!
  """
  Unix timestamp of the Ethereum transaction.
  """
  timestamp: BigInt!
  """
  Category of action, e.g., Deposit.
  """
  category: FlowActionCategory!
  """
  Contract through which the action was triggered.
  """
  contract: Bytes!
  """
  The Sablier fee paid in the native token of the chain (e.g., ETH for Mainnet).
  See https://docs.sablier.com/concepts/fees
  """
  fee: BigInt
  """
  Stream linked to this action, if any.
  """
  stream: FlowStream
  """
  Address of 1st actor. Who this is depends upon the action type, e.g. for Create, it is the sender.
  """
  addressA: Bytes
  """
  Address of 2nd actor. Who this is depends upon the action type, e.g. for Transfer, it is the recipient.
  """
  addressB: Bytes
  """
  1st amount. What this is depends upon the action type, e.g. for Deposit, it is the deposit amount.
  """
  amountA: BigInt
  """
  2nd amount. What this is depends upon the action type, e.g. for Withdraw, it is the refund amount.
  """
  amountB: BigInt
}

"""
A generic entity for tracking Lockup protocol actions.
"""
type LockupAction @entity(immutable: true) {
  """
  Unique identifier: `action-{chainId}-{txHash}-{logIndex}`
  """
  id: String!
  """
  Unique global id as tracked by the `Watcher` entity.
  """
  subgraphId: BigInt!
  """
  Block number of the Ethereum transaction.
  """
  block: BigInt!
  """
  The chain ID where the action was created (e.g., 137 for Polygon).
  """
  chainId: BigInt!
  """
  The tx.origin of the Ethereum transaction.
  """
  from: Bytes!
  """
  Hash of the Ethereum transaction.
  """
  hash: Bytes!
  """
  Unix timestamp of the Ethereum transaction.
  """
  timestamp: BigInt!
  """
  Category of action, e.g., Deposit.
  """
  category: LockupActionCategory!
  """
  Contract through which the action was triggered.
  """
  contract: Bytes!
  """
  The Sablier fee paid in the native token of the chain (e.g., ETH for Mainnet).
  See https://docs.sablier.com/concepts/fees
  """
  fee: BigInt
  """
  Stream linked to this action, if any.
  """
  stream: LockupStream
  """
  Address of 1st actor. Who this is depends upon the action type, e.g. for Create, it is the sender.
  """
  addressA: Bytes
  """
  Address of 2nd actor. Who this is depends upon the action type, e.g. for Transfer, it is the recipient.
  """
  addressB: Bytes
  """
  1st amount. What this is depends upon the action type, e.g. for Deposit, it is the deposit amount.
  """
  amountA: BigInt
  """
  2nd amount. What this is depends upon the action type, e.g. for Withdraw, it is the refund amount.
  """
  amountB: BigInt
}

"""
Creating streams in bulk is possible using the Sablier batch contracts.
"""
type FlowBatch @entity(immutable: true) {
  """
  Unique identifier: `batch-{chainId}-{txHash}-{batcher}`
  """
  id: String!
  """
  Hash of the Ethereum transaction that created this batch.
  """
  hash: Bytes
  """
  Timestamp of the transaction that created this batch.
  """
  timestamp: BigInt
  """
  The sender address that created this batch.
  """
  batcher: FlowBatcher
  """
  Index of the batch based on the `batchCounter` in the `Batcher` entity.
  """
  position: BigInt
  """
  Number of streams part of this batch.
  """
  size: BigInt!
  """
  Streams part of this batch.
  """
  streams: [FlowStream!]! @derivedFrom(field: "batch")
}

"""
Sender address that created batches.
"""
type FlowBatcher @entity(immutable: false) {
  """
  Unique identifier: `batcher-{chainId}-{sender}`
  """
  id: String!
  """
  Total number of batches started by this sender.
  """
  batchCounter: BigInt!
  """
  Batches started by this sender.
  """
  batches: [FlowBatch!]! @derivedFrom(field: "batcher")
}

"""
Creating streams in bulk is possible using the Sablier batch contracts.
"""
type LockupBatch @entity(immutable: true) {
  """
  Unique identifier: `batch-{chainId}-{txHash}-{batcher}`
  """
  id: String!
  """
  Hash of the Ethereum transaction that created this batch.
  """
  hash: Bytes
  """
  Timestamp of the transaction that created this batch.
  """
  timestamp: BigInt
  """
  The sender address that created this batch.
  """
  batcher: LockupBatcher
  """
  Index of the batch based on the `batchCounter` in the `Batcher` entity.
  """
  position: BigInt
  """
  Number of streams part of this batch.
  """
  size: BigInt!
  """
  Streams part of this batch.
  """
  streams: [LockupStream!]! @derivedFrom(field: "batch")
}

"""
Sender address that created batches.
"""
type LockupBatcher @entity(immutable: false) {
  """
  Unique identifier: `batcher-{chainId}-{sender}`
  """
  id: String!
  """
  Total number of batches started by this sender.
  """
  batchCounter: BigInt!
  """
  Batches started by this sender.
  """
  batches: [LockupBatch!]! @derivedFrom(field: "batcher")
}

"""
An address that has sent USDC to the Sablier treasury for the billing process.
"""
type Sponsor @entity(immutable: false) {
  """
  Unique identifier: `{chainId}_{address}`
  """
  id: String!
  """
  Address of the sponsor.
  """
  address: Bytes!
  """
  The chain ID where the sponsorship was made (sponsorships are chain-specific).
  """
  chainId: BigInt!
  """
  Number of sponsorships made by this sponsor.
  """
  sponsorshipCount: Int!
  """
  List of individual sponsorship transfers made by this sponsor.
  """
  sponsorships: [Sponsorship!]! @derivedFrom(field: "sponsor")
  """
  Cumulative raw USDC amount paid by the sponsor.
  """
  totalAmount: BigInt!
  """
  Human-readable cumulative USDC amount paid by the sponsor (e.g., "1729.12").
  """
  totalAmountDisplay: String!
}

"""
A single USDC transfer to the Sablier treasury. Immutable — one per Transfer event.
"""
type Sponsorship @entity(immutable: true) {
  """
  Unique identifier: `{chainId}_{txHash}_{logIndex}`
  """
  id: String!
  """
  Raw USDC amount.
  """
  amount: BigInt!
  """
  Human-readable USDC amount (e.g., "1719.12").
  """
  amountDisplay: String!
  """
  Block number of the transaction.
  """
  block: BigInt!
  """
  The ID of the chain where the transfer occurred (e.g., 1 for Ethereum).
  """
  chainId: BigInt!
  """
  Log index of the Transfer event within the transaction.
  """
  logIndex: Int!
  """
  Address of the transaction signer (may differ from `from` for contract wallets).
  """
  sender: Bytes!
  """
  The sponsor who made this transfer.
  """
  sponsor: Sponsor!
  """
  Unix timestamp of the transaction.
  """
  timestamp: BigInt!
  """
  Hash of the transaction.
  """
  txHash: Bytes!
}

"""
A Sablier protocol contract
"""
type Contract @entity(immutable: false) {
  """
  Unique identifier: contract-{chainId}-{address}
  """
  id: String!
  """
  Contract address
  """
  address: Bytes!
  """
  Contract alias (e.g., "FL", "LK")
  """
  alias: String!
  """
  Contract category (e.g., "Flow", "Lockup")
  """
  category: String!
  """
  The chain ID where the contract exists
  """
  chainId: BigInt!
}

"""
Older streams are no longer indexed.
See https://x.com/Sablier/status/1914326014995620114
"""
type DeprecatedStream @entity(immutable: true) {
  """
  Unique identifier: \`{contractAddress}-{chainId}-{tokenId}\`
  """
  id: String!
  """
  The chain ID where the stream was created (e.g., 137 for Polygon).
  """
  chainId: BigInt!
  """
  The address of the contract that created the stream.
  """
  contractAddress: Bytes!
  """
  The id provided by the NFT contract. It's the ERC-721 tokenId.
  """
  tokenId: BigInt!
  """
  Hash of the Ethereum transaction that created this stream.
  """
  hash: Bytes!
  """
  Unix timestamp of the Ethereum transaction that created this stream.
  """
  timestamp: BigInt!
}

"""
See https://docs.sablier.com/concepts/lockup/segments
"""
type Segment @entity(immutable: true) {
  """
  Unique identifier: `segment-{streamId}-{position}`
  """
  id: String!
  """
  Amount distributed by this segment.
  """
  amount: BigInt!
  """
  Total amount distributed at `endTime`. This is the sum of this segment's amount and all previous segments' amounts.
  """
  endAmount: BigInt!
  """
  Unix timestamp indicating the end of the segment.
  """
  endTime: BigInt!
  """
  Exponent used for the streamed amount calculations.
  See https://github.com/sablier-labs/lockup/blob/v2.0/src/types/DataTypes.sol#L279-L288
  """
  exponent: BigInt!
  """
  Position of the segment inside the array.
  """
  position: BigInt!
  """
  Total amount distributed by the stream at `startTime`. This is the sum of all previous segments' amounts.
  """
  startAmount: BigInt!
  """
  Unix timestamp indicating the start of the segment.
  This is also the end time of the previous segment or, if this is the first segment, it is the start time of the stream.
  """
  startTime: BigInt!
  """
  The stream in which this segment was created.
  """
  stream: LockupStream!
}

"""
See https://docs.sablier.com/concepts/lockup/tranches
"""
type Tranche @entity(immutable: true) {
  """
  Unique identifier: `tranche-{streamId}-{position}`
  """
  id: String!
  """
  Amount distributed by this tranche.
  """
  amount: BigInt!
  """
  Total amount distributed at `endTime`. This is the sum of this tranche's amount and all previous tranches' amounts.
  """
  endAmount: BigInt!
  """
  Unix timestamp indicating the end of the tranche.
  """
  endTime: BigInt!
  """
  Position of the tranche inside the array.
  """
  position: BigInt!
  """
  Total amount distributed by the stream at `startTime`. This is the sum of all previous tranches' amounts.
  """
  startAmount: BigInt!
  """
  Unix timestamp indicating the start of the tranche.
  This is also the end time of the previous tranche or, if this is the first tranche, it is the start time of the stream.
  """
  startTime: BigInt!
  """
  The stream in which this tranche was created.
  """
  stream: LockupStream!
}

```