Operation

POST /graphql

Single GraphQL endpoint at POST /api/v1/graphql mirroring core REST resources (advertisers, deals, transactions, clicks, publishers, networks, tags, account activity summaries). Authentication (`X-Api-Key` / OAuth) and Pundit scoping match REST; the schema defines no mutations. List fields return `{ nodes, pageInfo }` with offset pagination (`page`, `perPage` max 200, `page * perPage` ≤ 10,000); pass `includeTotal: true` only when a total count is required (totals capped at 100,000). Deals: `deals` returns visible deals only (`hidden: false`) by default, matching GET /deals; pass `includeHidden: true` to include authorized hidden deals; filters include advertiserId, exclusive, featured, device, activeOn; use `deal(id)` for a known id (returns a hidden deal when authorized). Clicks: `clicks` requires startDate and endDate (inclusive, ≤ 90 days) and accepts optional advertiserId and publisherId. Transactions: `transactions` requires a bound — advertiserId, publisherId, networkId, or both startDate and endDate — and does not invent a default 30-day window like REST; status is a list of PENDING/APPROVED/PAID/CORRECTED. Terms: `terms` returns AI-extracted advertiser commission terms scoped by TermPolicy (paid publishers / agency-managed paid publishers; admins see all); filters include advertiserId, campaignId, and free-text query; use `term(id)` for a known id. Prefer GET /deals, GET /clicks, and GET /transactions for standard list shapes; use this operation (or the MCP `graphql_query` tool) when you need a custom selection set or multi-resource read. Full human docs: /api_documentation/graphql.

Operation ID: executeGraphql · Tags: GraphQL, Deals, Clicks, Transactions

Parameters

This operation does not define any parameters.

Request Body

Required: Yes
{
  "required": true,
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/GraphQLQueryRequest"
      },
      "examples": {
        "deals_visible": {
          "summary": "Visible deals for an advertiser",
          "description": "Lists non-hidden deals. Hidden deals are excluded by default.",
          "value": {
            "query": "query($advertiserId: ID) { deals(advertiserId: $advertiserId, perPage: 10, includeTotal: true) { nodes { id name exclusive featured effectiveAt expiresAt advertiser { id name } } pageInfo { totalCount hasNextPage } } }",
            "variables": {
              "advertiserId": "123"
            }
          }
        },
        "deals_include_hidden": {
          "summary": "Include hidden deals (opt-in)",
          "description": "Pass includeHidden: true to include hidden deals the caller is authorized to see. Results stay scoped by DealPolicy.",
          "value": {
            "query": "query($advertiserId: ID) { deals(advertiserId: $advertiserId, includeHidden: true, perPage: 10) { nodes { id name hidden } pageInfo { hasNextPage } } }",
            "variables": {
              "advertiserId": "123"
            }
          }
        },
        "clicks_with_advertiser": {
          "summary": "Clicks for a ≤90-day window with advertiserId",
          "description": "startDate and endDate are required. advertiserId is applied in Searchkick and SQL fallback.",
          "value": {
            "query": "query($from: IsoDate!, $to: IsoDate!, $advertiserId: ID) { clicks(startDate: $from, endDate: $to, advertiserId: $advertiserId, perPage: 50) { nodes { id clickDate clickCount advertiserName networkName } pageInfo { hasNextPage } } }",
            "variables": {
              "from": "2026-05-19",
              "to": "2026-05-26",
              "advertiserId": "123"
            }
          }
        },
        "transactions_bounded": {
          "summary": "Bounded transactions with normalized status",
          "description": "Both startDate and endDate form a bound. Optional status filters use TransactionStatus enums.",
          "value": {
            "query": "query($from: IsoDate!, $to: IsoDate!) { transactions(startDate: $from, endDate: $to, status: [APPROVED, PAID], perPage: 25) { nodes { id status saleAmount commissionAmount statusTimestamps { pendingAt approvedAt paidAt correctedAt } advertiser { id name } } pageInfo { hasNextPage } } }",
            "variables": {
              "from": "2026-04-01",
              "to": "2026-04-30"
            }
          }
        },
        "terms_for_advertiser": {
          "summary": "Commission terms for an advertiser",
          "description": "Returns AI-extracted commission terms the caller is authorized to see (TermPolicy paid-account scope).",
          "value": {
            "query": "query($advertiserId: ID) { terms(advertiserId: $advertiserId, perPage: 10, includeTotal: true) { nodes { id cid name summary advertiser { id name } } pageInfo { totalCount hasNextPage } } }",
            "variables": {
              "advertiserId": "123"
            }
          }
        }
      }
    }
  }
}

Responses

Content Types

  • application/json
{
  "description": "GraphQL execution result (data and/or errors). Auth failures use the REST Unauthorized envelope with HTTP 401.",
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/GraphQLExecutionResult"
      },
      "examples": {
        "deals_success": {
          "summary": "Deals connection",
          "value": {
            "data": {
              "deals": {
                "nodes": [
                  {
                    "id": "456",
                    "name": "20% off sitewide",
                    "exclusive": true,
                    "featured": false,
                    "advertiser": {
                      "id": "123",
                      "name": "Example Brand"
                    }
                  }
                ],
                "pageInfo": {
                  "totalCount": 1,
                  "hasNextPage": false
                }
              }
            }
          }
        },
        "validation_error": {
          "summary": "Unbounded transactions rejected",
          "value": {
            "data": null,
            "errors": [
              {
                "message": "transactions requires advertiserId, publisherId, networkId, or both startDate and endDate"
              }
            ]
          }
        }
      }
    }
  }
}

{
  "$ref": "#/components/responses/Unauthorized"
}

API Playground

The in-page tester only supports GET. For POST, use the sample curl below or the dedicated resource docs (e.g. Contacts, Link Builder). Sign in to enable live testing with your API key.

Action Method Endpoint Description
Execute a read-only GraphQL query POST /api/v1/graphql OpenAPI operationId: executeGraphql.

Example request (replace YOUR_API_KEY or sign in above):

curl -X POST "https://app.hienergy.ai/api/v1/graphql" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Accept: application/json"
  -H "Content-Type: application/json" \
  -d '{"query":"query($advertiserId: ID) { deals(advertiserId: $advertiserId, perPage: 10, includeTotal: true) { nodes { id name exclusive featured effectiveAt expiresAt advertiser { id name } } pageInfo { totalCount hasNextPage } } }","variables":{"advertiserId":"123"}}'

GraphQL deals / clicks / transactions field reference: GraphQL API docs. Additional named examples live in the request body schema above and in GET /api/v1/schema under paths./graphql.post.requestBody.

Ask Dex AIIntegration help

If this page feels TLDR, ask Dex AI.

Dex AI speaks your language, and all the other languages you may not. It will write the integration for you with the right endpoint and headers in one plain-English answer.