Read a Pipe's Snapshots and Operations

Query a pipe's snapshots, download the stored JSON, and follow the change-management operations run against it.

Before You Begin

🔗 Use the GraphQL Playground to execute the queries in this guide.

➡️ New to GraphQL? Learn how to navigate the Playground with our Playground Basics Guide.

Prerequisites

  1. Authentication: Use a Service Account token (Personal Access Tokens are deprecated).
  2. Permissions: Your token must have Admin (manage) permission on the target pipe. All three fields in this guide require it.
  3. Pipe ID: The ID of the pipe you want to inspect. See Get resource IDs.
  4. At least one snapshot: Snapshots are created on demand, so a pipe that was never snapshotted returns nothing. Create one with Create a Pipe Snapshot.

Step 1: Read the Latest Snapshot

snapshot returns a single snapshot of the pipe. Called with no argument it returns the pipe's latest uploaded snapshot, which is the one a restore can target.

query {
  pipe(id: 123) {
    snapshot {
      id
      versionId
      label
      sequenceIndex
      status
      metrics
      signedUrl
      uploadedAt
      createdAt
      createdBy {
        id
        name
      }
    }
  }
}

Sample Response:

{
  "data": {
    "pipe": {
      "snapshot": {
        "id": "456",
        "versionId": "9f1c2d34-5678-49ab-bcde-0123456789ab",
        "label": "Before the Q3 automation rework",
        "sequenceIndex": 3,
        "status": "UPLOADED",
        "metrics": {
          "entity_counts": { "phases": 5, "fields": 42, "automations": 3 },
          "byte_size": 184320,
          "compressed_byte_size": 20480
        },
        "signedUrl": "https://files.pipefy.com/org/org-uuid-here/repo_snapshots/pipe-uuid-here/9f1c2d34-5678-49ab-bcde-0123456789ab.json?signature=...",
        "uploadedAt": "2026-06-25T12:35:01Z",
        "createdAt": "2026-06-25T12:34:56Z",
        "createdBy": { "id": "789", "name": "Ana Souza" }
      }
    }
  }
}

A pipe with no uploaded snapshot returns snapshot: null, even when a PENDING or FAILED snapshot exists.

Step 2: Fetch One Specific Version

Pass versionId to address a snapshot directly. Unlike the no-argument form, this one returns the snapshot whatever its status, so it is how you poll a snapshot you just created until it reaches UPLOADED or FAILED.

query($id: ID!, $versionId: ID) {
  pipe(id: $id) {
    snapshot(versionId: $versionId) {
      versionId
      status
      error
      signedUrl
    }
  }
}

Query Variables:

{
  "id": 123,
  "versionId": "9f1c2d34-5678-49ab-bcde-0123456789ab"
}

A versionId that does not belong to this pipe returns snapshot: null.

Step 3: Page Through the Snapshot History

snapshots is a Relay connection listing every snapshot of the pipe, most recent first, including PENDING and FAILED ones. Use first and after to page.

query($id: ID!, $first: Int!, $after: String) {
  pipe(id: $id) {
    snapshots(first: $first, after: $after) {
      edges {
        cursor
        node {
          versionId
          label
          sequenceIndex
          status
          createdAt
        }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
  }
}

Query Variables:

{
  "id": 123,
  "first": 2,
  "after": null
}

Sample Response:

{
  "data": {
    "pipe": {
      "snapshots": {
        "edges": [
          {
            "cursor": "MQ",
            "node": {
              "versionId": "9f1c2d34-5678-49ab-bcde-0123456789ab",
              "label": "Before the Q3 automation rework",
              "sequenceIndex": 3,
              "status": "UPLOADED",
              "createdAt": "2026-06-25T12:34:56Z"
            }
          },
          {
            "cursor": "Mg",
            "node": {
              "versionId": "1a2b3c4d-5e6f-4789-abcd-ef0123456789",
              "label": null,
              "sequenceIndex": 2,
              "status": "UPLOADED",
              "createdAt": "2026-06-18T09:02:11Z"
            }
          }
        ],
        "pageInfo": { "hasNextPage": true, "endCursor": "Mg" }
      }
    }
  }
}

Feed endCursor back as after to fetch the next page, and stop when hasNextPage is false. See Pagination basics.

Step 4: Follow the Operations Run Against the Pipe

Structural operations on a pipe (a restore, a deploy, a sandbox version build) each get their own record with a kind, a status and, on failure, the reason. operations lists them, most recent first.

query {
  pipe(id: 123) {
    operations {
      id
      kind
      status
      error
      createdAt
      updatedAt
    }
  }
}

Sample Response:

{
  "data": {
    "pipe": {
      "operations": [
        {
          "id": "9001",
          "kind": "GENERATE_ENVIRONMENT",
          "status": "RUNNING",
          "error": null,
          "createdAt": "2026-06-25T13:00:00Z",
          "updatedAt": "2026-06-25T13:00:04Z"
        },
        {
          "id": "8874",
          "kind": "RESTORE",
          "status": "FAILED",
          "error": "phase 42 could not be reconciled",
          "createdAt": "2026-06-24T18:20:00Z",
          "updatedAt": "2026-06-24T18:21:37Z"
        }
      ]
    }
  }
}

To check whether anything is under way right now, filter by status:

query {
  pipe(id: 123) {
    operations(status: [PENDING, RUNNING]) {
      id
      kind
      status
    }
  }
}

An empty array means the pipe is idle, so a new restore or version build can be started.

Step 5: Read the Operations Sourced From One Snapshot

The reverse direction is available on the snapshot itself: operations on a snapshot lists the operations that used it as their source, most recent first, as a Relay connection.

query {
  pipe(id: 123) {
    snapshot {
      versionId
      operations {
        nodes {
          id
          kind
          status
          error
        }
      }
    }
  }
}

This is how you confirm that the restore you requested with Restore a Pipe to a Snapshot actually finished: find the RESTORE operation on the snapshot you targeted and read its status.

Response Fields

Snapshot

  • versionId: Unique identifier for the snapshot version. Use it to address one snapshot unambiguously in snapshot(versionId:), renameRepoSnapshot and restoreRepoToSnapshot.
  • sequenceIndex: Monotonic per-pipe ordering position among uploaded snapshots, starting at 1. Assigned on upload, so it is null while PENDING and stays null for a snapshot that FAILED. The highest one is the pipe's latest snapshot.
  • label: Human-readable name set through renameRepoSnapshot. null for snapshots that were never named.
  • status: PENDING (queued, generation unfinished), UPLOADED (stored, signedUrl available) or FAILED (generation failed permanently, see error).
  • metrics: entity_counts, byte_size and compressed_byte_size. Empty ({}) while PENDING.
  • signedUrl: Temporary pre-signed URL to download the snapshot JSON. null until the snapshot is UPLOADED, and it expires, so fetch it when you are about to download rather than storing it.
  • createdBy: The user who requested the snapshot. null for snapshots taken before authorship was recorded and for authors whose account was anonymized.

Operation

  • kind: RESTORE (pipe structure reconciled to a snapshot), DEPLOY (a version deployed onto the pipe) or GENERATE_ENVIRONMENT (an editable sandbox version built by cloning the pipe from a snapshot).
  • status: PENDING (queued), RUNNING (executing), SUCCEEDED or FAILED.
  • error: Why the operation failed. null unless status is FAILED.

Key Notes

  • Admin only: all three fields authorize Admin (manage) on the pipe. A token without it receives a PERMISSION_DENIED error and the field resolves to null, so a member cannot discover that a pipe has snapshots at all.
  • snapshot with no argument skips unfinished snapshots: it returns the latest UPLOADED snapshot only. Pass versionId to read a PENDING or FAILED one.
  • snapshots includes every status: the list is unfiltered, so a failed generation shows up there with its error. Filter client-side on status if you only want usable snapshots.
  • Cursors are positional: a snapshot created while you page through the list shifts the window, so one row can repeat or be skipped. Page through the history in one go rather than holding a cursor across a long interval.
  • operations is not paginated: it returns a plain list of every matching operation, so use the status argument to keep the response bounded.
  • Related operations: Create a Pipe Snapshot, Rename a Pipe Snapshot, Restore a Pipe to a Snapshot and Open a Pipe Sandbox Version.