Combined API Usage Stats

Retrieve combined API-call usage, per-organization breakdown, and top consumers across a set of organizations the authenticated user can access.

Before You Begin

Prerequisites

  • A role that grants the Usage Stats permission in each organization you want to include. This is the same permission that controls access to the Usage Statistics page in the Pipefy app — organizations where you do not have it will be silently dropped from the response (see partial below). Organization admins manage this under Roles & Permissions.

Step 1. List the organizations you can query

The combined query expects an explicit list of organization UUIDs. The easiest way to obtain that list is the myUsageStatsOrganizations query, which returns every organization where the authenticated user has the Usage Stats permission:

{
  myUsageStatsOrganizations {
    uuid
    name
  }
}

Pick the uuid values you want to combine and pass them to apiUsageStatsCombined (1 to 25 UUIDs per call).

Step 2. Query combined API usage

Run the following query with the list of organization UUIDs and the desired time period:

query apiUsageStatsCombined(
  $organizationUuids: [ID!]!
  $period: PeriodFilter!
  $dimension: APIUsageDimension
) {
  apiUsageStatsCombined(organizationUuids: $organizationUuids, period: $period) {
    total {
      usage
      limit
    }
    byOrganization {
      organizationUuid
      organizationName
      usage
      limit
    }
    topItems(dimension: $dimension) {
      dimension
      metric
      organizationUuid
      organizationName
    }
    filterDate {
      from
      to
    }
    partial
  }
}

Input Explanation:

  • organizationUuids: List of organization UUIDs to aggregate. Must contain between 1 and 25 entries. Unauthorized or unknown UUIDs are silently dropped from byOrganization and flip partial to true.
  • period: Time window for the stats. Use current_month, last_month, or last_3_months.
  • dimension (on topItems): How to group the top-10 leaderboard. Optional; defaults to OPERATION_NAME.
    • OPERATION_NAME: Groups by the GraphQL operation name set by the client. Operations are summed across organizations, so organizationUuid / organizationName in each row are null.
    • PERSONAL_ACCESS_TOKEN: Groups by personal access token. Each row is scoped to one organization, so organizationUuid / organizationName are populated.
    • SERVICE_ACCOUNT: Groups by service account. Each row is scoped to one organization, so organizationUuid / organizationName are populated.

Sample response (with dimension: OPERATION_NAME, the default):

{
  "data": {
    "apiUsageStatsCombined": {
      "total": {
        "usage": 1842,
        "limit": 20000
      },
      "byOrganization": [
        {
          "organizationUuid": "8a1c4f10-1111-4d2c-9c2a-abc123def456",
          "organizationName": "Acme Corp",
          "usage": 1240,
          "limit": 10000
        },
        {
          "organizationUuid": "b27d5e21-2222-4a3b-8d1b-def456abc789",
          "organizationName": "Globex",
          "usage": 602,
          "limit": 10000
        }
      ],
      "topItems": [
        {
          "dimension": "GetCards",
          "metric": 612,
          "organizationUuid": null,
          "organizationName": null
        },
        {
          "dimension": "Not specified",
          "metric": 388,
          "organizationUuid": null,
          "organizationName": null
        },
        {
          "dimension": "UpdatePipe",
          "metric": 207,
          "organizationUuid": null,
          "organizationName": null
        }
      ],
      "filterDate": {
        "from": "2026-05-01T00:00:00Z",
        "to": "2026-05-27T00:00:00Z"
      },
      "partial": false
    }
  }
}

Sample response (with dimension: SERVICE_ACCOUNT):

{
  "data": {
    "apiUsageStatsCombined": {
      "total": { "usage": 1842, "limit": 20000 },
      "byOrganization": [
        {
          "organizationUuid": "8a1c4f10-1111-4d2c-9c2a-abc123def456",
          "organizationName": "Acme Corp",
          "usage": 1240,
          "limit": 10000
        },
        {
          "organizationUuid": "b27d5e21-2222-4a3b-8d1b-def456abc789",
          "organizationName": "Globex",
          "usage": 602,
          "limit": 10000
        }
      ],
      "topItems": [
        {
          "dimension": "HR Integration Bot",
          "metric": 740,
          "organizationUuid": "8a1c4f10-1111-4d2c-9c2a-abc123def456",
          "organizationName": "Acme Corp"
        },
        {
          "dimension": "Billing Sync",
          "metric": 402,
          "organizationUuid": "b27d5e21-2222-4a3b-8d1b-def456abc789",
          "organizationName": "Globex"
        }
      ],
      "filterDate": {
        "from": "2026-05-01T00:00:00Z",
        "to": "2026-05-27T00:00:00Z"
      },
      "partial": false
    }
  }
}

Response Breakdown:

Key Fields:

  • total.usage: Sum of API-call usage across the organizations returned in byOrganization.
  • total.limit: Sum of per-organization limits. null when no organization in the response has a contracted limit; organizations with a null per-org limit are treated as 0 in the sum.
  • byOrganization: One row per organization that responded successfully, ordered by usage descending (ties broken by organization name). Organizations the caller is unauthorized for, or whose per-org fetch failed, are omitted.
  • topItems: The top consumers across the returned organizations for the requested dimension. See Key Notes for sort order and the lazy-resolution behavior.
  • partial: true when at least one input UUID is missing from byOrganization. This happens for two reasons: (1) the caller does not have the Usage Stats permission in that organization, or (2) the per-org fetch failed transiently. The response does not distinguish between the two — re-run the query if you suspect a transient failure.
  • filterDate: Resolved from/to boundaries of the requested period, useful for labeling charts.

Key Notes

  • Top-items sort and limit. topItems returns up to 10 rows, sorted by metric in descending order. Ties are not broken deterministically.
  • Switching dimension is cheap; switching period or organizationUuids is not. topItems(dimension:) is resolved lazily on a separate backend call from total / byOrganization. Re-selecting topItems with a different dimension in the same query (or a follow-up request) only recomputes the leaderboard — the usage and limit numbers are not refetched. Changing period or organizationUuids, however, invalidates everything and triggers a full recomputation.
  • total.limit null handling. If no organization in the response has a contracted API limit, total.limit is null. If at least one does, the sum is returned and orgs without a limit count as 0 toward it — this is intentional so that mixing contracted and free-tier orgs in one combined view still produces a usable total.
  • Use myUsageStatsOrganizations to discover the input list. It returns exactly the organizations the authenticated user is eligible to query, so feeding its uuid values into apiUsageStatsCombined guarantees partial: false for the authorization-drop case.