Hi Energy AI API Documentation

Overview

Hi Energy pulls in data from FlexOffers, CJ, Rakuten, Impact, Awin, Partnerize, Pepperjam, and ShareASale, enriches and normalizes the data with proprietary sources, and makes it available to users via our API.

AI-Friendly API

This API is specifically designed for AI agents and chatbots. It features:

  • Live pagination guidance - Offset-style meta by default, advertiser cursor compatibility when explicitly requested
  • Structured responses - Consistent JSON format
  • Error handling - Clear error codes and messages
  • Rate limiting - Predictable request limits
  • Dry run mode - Test without making changes

Quick Reference

Essential information for getting started quickly with the Hi Energy AI API.

API Base URL
https://app.hienergy.ai/api/v1

All API endpoints start with this base URL

Authentication
X-Api-Key: YOUR_API_KEY

Include this header in all requests

Rate Limits
1,000 or 10,000/hour

Hi Energy: 1,000/hour; other publishers: 10,000/hour

Response Format
JSON with pagination

All responses include pagination metadata

Quick Start Examples
Get Advertisers
curl -H "X-Api-Key: YOUR_KEY" \
  "https://app.hienergy.ai/api/v1/advertisers?limit=5"
Search Deals
curl -H "X-Api-Key: YOUR_KEY" \
  "https://app.hienergy.ai/api/v1/deals?active=true"
Domain Search
curl -H "X-Api-Key: YOUR_KEY" \
  "https://app.hienergy.ai/api/v1/advertisers?domain=amazon.com"
Initialize MCP
curl -X POST https://app.hienergy.ai/mcp \
  -H "X-Api-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25"}}'
Detailed API Documentation
Deals API

Complete guide to retrieving and filtering affiliate deals

View Documentation
Advertisers API

Comprehensive guide to searching and retrieving advertiser data

View Documentation
Transactions API

Complete guide to retrieving and analyzing affiliate transactions

View Documentation
Contacts API

Search contacts by domain, advertiser, or email

View Documentation

API Playground

Use the table below to see how to perform common actions for each endpoint. Click Test to run a request and preview the JSON response inline, or Open to view the endpoint in a new tab. Sign in to enable live testing with your API key.

Action Method Endpoint Description
Universal search GET /api/v1/search One-shot Searchkick omnibox across advertisers, publishers, agencies, deals, contacts, and (admin) users.
List deals GET /api/v1/deals Offset pagination; optional page, per_page, or limit plus filters.
Get single deal GET /api/v1/deals/:id Fetch one deal by ID.
List advertisers GET /api/v1/advertisers Search/filter advertisers.
Get single advertiser GET /api/v1/advertisers/:id Fetch one advertiser by ID or slug.
Similar advertisers GET /api/v1/advertisers/:id/similar_advertisers Competitive set and affiliate discovery for one advertiser.
Advertiser contacts GET /api/v1/advertisers/:id/contacts The same team-tab contact list shown on the advertiser page.
List opportunities GET /api/v1/opportunities Searchkick-backed list of advertisers a publisher should apply to, sorted by aggregate revenue columns.
List transactions GET /api/v1/transactions Filter by date, advertiser, network.
Search contacts GET /api/v1/contacts Filter by domain, advertiser, email.
List verticals GET /api/v1/verticals Industry categories for filtering.
Search tags GET /api/v1/tags Search tag names (Searchkick-first).
List tag advertisers GET /api/v1/tags/:id/advertisers Advertisers for a tag (no total count).
MCP reachability (GET) GET /mcp Returns authenticated setup JSON (protocol version, integration URL, OAuth hints).
MCP integration JSON GET /mcp/integration Machine-readable ChatGPT / Claude / Responses API wiring metadata.
Initialize MCP POST /mcp Start an MCP session with JSON-RPC initialize.
List publishers GET /api/v1/publishers Searchkick-backed publisher list; filter by q, company_type, publisher_type, network_id.
Show publisher GET /api/v1/publishers/:id View publisher and network keys.
Update publisher PATCH /api/v1/publishers/:id Update publisher/network credentials.
List agencies GET /api/v1/agencies Discover agencies with their associated publishers.
List networks GET /api/v1/networks Discover supported affiliate networks (FlexOffers, CJ, Rakuten, Impact, Awin, etc.).
List clicks GET /api/v1/clicks Aggregate clicks per advertiser for a date window (up to 90 days).
List reports GET /api/v1/reports Major report aliases plus raw materialized-view reports.
Get report GET /api/v1/reports/:id Fetch one report payload (supports period and publisher_id filters).
Search users GET /api/v1/users Search users in your accessible scope.
Create user POST /api/v1/users Create user in your own publisher/agency/network scope (admins: any publisher).
List status changes GET /api/v1/status_changes Filter by from_status, to_status, advertiser.
Generate tracking link POST /api/v1/deeplinks/generate Generate affiliate tracking link for any URL (requires link_generator_enabled).
Discover tools GET /api/v1/tools Machine-readable JSON Schema catalog of every AI/MCP tool.
Fetch OpenAPI schema GET /api/v1/schema Download the full OpenAPI 3.0 schema for code generation.
GET /api/v1/search?q=nike v1

Universal Searchkick omnibox — returns advertisers, publishers, agencies, deals, and contacts in one shot. Try it first when a brand, domain, or email could map to multiple record types.


    
GET /api/v1/search?q=fashion&types=advertisers,deals&per_type_limit=5 v1

Universal search scoped to a subset of types, tuned for a search bar (top-5 advertisers + deals).


    
GET /api/v1/deals v1

Search deals (offset-style meta pagination).


    
GET /api/v1/deals/:id v1

Show a single deal (example ID).


    
GET /api/v1/advertisers v1

Search advertisers (offset-style meta by default; cursor compatibility when requested).


    
GET /api/v1/advertisers/:id v1

Show a single advertiser (example).


    
GET /api/v1/transactions v1

Search transactions (offset-style meta pagination).


    
GET /api/v1/transactions/:id v1

Show a single transaction (requires an ID; use index first).


    
GET /api/v1/contacts v1

Search contacts.


    
GET /api/v1/verticals v1

List vertical tags.


    
GET /api/v1/tags?search=sport v1

Search tags (Searchkick-first).


    
GET /api/v1/tags/:id/advertisers v1

Advertisers for a tag (example slug).


    
GET /api/v1/tools v1

Discover available tools (JSON Schema).


    
GET /api/v1/schema v1

Download API schema.


    
GET /mcp MCP

MCP GET bootstrap: same metadata clients use for connectivity checks (not JSON-RPC).


    
GET /mcp/integration.json MCP

Download the integration JSON used by ChatGPT marketplace and Claude connectors.


    
POST /mcp — initialize (JSON-RPC) MCP

Negotiate MCP protocolVersion 2025-11-25 and read server capabilities from the browser.


    
GET /api/v1/domains/search v1

Search advertisers by domain.


    
GET /api/v1/publishers v1

List publishers (Searchkick-backed). Add `q=` for text search or `company_type=`/`publisher_type=` to filter.


    
GET /api/v1/publishers?q=content v1

Publisher text search — matches `name`, `domain`, and `slug` via Elasticsearch.


    
GET /api/v1/opportunities v1

Top opportunity advertisers for the caller's publisher, ordered by `global_transactions_count` by default.


    
GET /api/v1/opportunities?sort=global_total_sales&order=desc v1

Opportunities sorted by aggregate sales (highest first) — useful for leaderboard prompts.


    
GET /api/v1/agencies v1

List agencies and the publishers they manage.


    
GET /api/v1/networks v1

Supported affiliate networks (FlexOffers, CJ, Rakuten, Impact, Awin, Partnerize, Pepperjam, ShareASale).


    
GET /api/v1/clicks v1

Clicks aggregated per advertiser for a rolling 7-day window (limit 90 days).


    
GET /api/v1/status_changes v1

Historical advertiser status transitions (approved, applied, rejected, etc.). Add `from_status=` / `to_status=` to narrow.


    
GET /api/v1/reports v1

Catalog of major report aliases plus raw materialized-view reports with `when_to_use` hints.


    
GET /api/v1/reports/top_advertisers_by_sales v1

One-shot leaderboard report (top advertisers by sales). Most report IDs accept `period=` and `limit=`.


    
GET /api/deals legacy

Legacy deals endpoint (offset pagination).


    
GET /api/deals/:id legacy

Legacy deal show (requires an ID; use index first).


    
GET /api/advertisers legacy

Legacy advertisers endpoint (offset pagination).


    
GET /api/domains/search legacy

Legacy domain search.


    

Common Scenarios

Real-world parameter combinations that stitch together filters, sorting, and pagination. Click Test on any card to see the live JSON response.

GET /api/v1/advertisers?vertical=fashion&country=US&with_deals=true scenario

Top US fashion advertisers that currently have at least one active deal.


    
GET /api/v1/advertisers?sort_by=global_total_sales&sort_order=desc scenario

Advertiser leaderboard by aggregate sales — useful for "biggest programs" prompts.


    
GET /api/v1/deals?active=true&country_code=US&sort=expires_at scenario

Active US deals sorted by soonest expiration — great for deal-of-the-day content.


    
GET /api/v1/deals?advertiser_id=…&per_page=10 scenario

All currently published deals for a single advertiser (example uses the first approved advertiser).


    
GET /api/v1/transactions?start_date=30d&end_date=today scenario

Last-30-days transactions for the caller's publisher, most recent first.


    
GET /api/v1/transactions?sort_by=sale_amount&sort_order=desc scenario

Biggest transactions by sale amount — pairs well with a follow-up advertiser lookup.


    
GET /api/v1/contacts?advertiser_domain=amazon.com scenario

Contacts whose advertiser resolves to a given public domain — powers "who do I email about amazon.com?"


    
GET /api/v1/contacts?q=partnerships scenario

Full-text contact search across emails, names, titles, and company names.


    
GET /api/v1/status_changes?to_status=approved scenario

Recent advertiser approvals for the caller's publisher (great for onboarding dashboards).


    
GET /api/v1/clicks?start_date=…&end_date=… scenario

Last-30-days clicks aggregated per advertiser — up to a 90-day window is supported.


    
GET /api/v1/tags?search=shopping&per_page=10 scenario

Tag typeahead — Searchkick-backed prefix search across tag names.


    
GET /api/v1/advertisers/:id/similar_advertisers scenario

Competitive set for a seed advertiser — great follow-up after a universal search hit.


    
GET /api/v1/advertisers/:id/contacts scenario

All known contacts for a specific advertiser — mirrors the team tab in the UI.


    
GET /api/v1/advertisers?cursor=0&limit=50 scenario

Advertiser cursor-compatibility mode — use when you need stable pagination over very large result sets.


    
GET /api/v1/reports/top_advertisers_by_sales?limit=25 scenario

Top-25 advertisers by sales — one of the major report aliases exposed to the MCP server.


    
GET /api/v1/search?q=beauty&types=advertisers,deals&per_type_limit=5 scenario

Universal search with explicit type caps — good template for autocomplete or RAG chunking.


    
GET /api/v1/opportunities?sort=global_total_sales&order=desc scenario

Publisher opportunity pipeline sorted by trailing sales — pairs with apply-to-program workflows.


    
GET /api/v1/users?q=admin&per_page=5 scenario

Scoped user lookup — respects publisher/agency/network visibility for the caller.


    
GET /api/v1/deals?dry_run=true scenario

Shape-check any list endpoint without consuming rate limit — returns a sample response schema.


    

GET /api/v1/deals

GET /api/v1/deals GET

Search exclusive and standard deal inventory with offset-style pagination. Responses return deals.data plus meta fields such as current_page, next_page, and per_page.

Live behavior: if you omit status, the controller defaults active=true. Use limit to cap page size, or send page and per_page explicitly.
Exclusive deals: many records on this endpoint are negotiated for HiEnergy clients and may not exist in generic affiliate-network deal feeds.
Parameters
Parameter Type Description Example
Pagination
limit integer Upper bound on page size. The controller defaults to per_page=500 and clamps to 500. 25
page, per_page integer Offset pagination controls. Use these when you want predictable page navigation through meta.next_page. page=2&per_page=50
include_total boolean Request exact or estimated total counts in meta when you need totals for UI or reporting. true
Common Filters
q, query, search string Free-form deal lookup. The controller normalizes this input before filtering. vpn
country, country_code string Country filter. The underlying deal filtering normalizes country tags to lowercase internally. US
exclusive boolean Return only exclusive deals. true
featured boolean Return only featured deals. true
active, status boolean/string Use active=true for live offers or an explicit status when you need non-default states. active=true
vertical_id string Filter by vertical or category id. 1
deal_type string Filter by deal kind: free_shipping, coupon, promotion, seasonal_holiday. Discover values via GET /api/v1/deals/types. coupon
deal_kind string Legacy alias for deal_type. Both are accepted; deal_type wins if both are sent. coupon
deal_visibility string Opt into hidden deals. Omit (default) for visible-only; all includes hidden + visible; hidden returns only hidden rows. Authorization is still enforced. all
dry_run boolean Validate your integration wiring without mutating anything. true
AEO-Friendly Examples
Answer “show me active US deals”
curl -H "X-Api-Key: YOUR_KEY" \
  "https://app.hienergy.ai/api/v1/deals?active=true&country=US&limit=25"

Good for affiliate content pages, AI shopping assistants, or “best deals in the US” answers.

Answer “show me exclusive VPN offers”
curl -H "X-Api-Key: YOUR_KEY" \
  "https://app.hienergy.ai/api/v1/deals?q=vpn&exclusive=true&limit=25"

Use free-form search first, then layer on structured filters like exclusive or country.

Walk through pages safely
curl -H "X-Api-Key: YOUR_KEY" \
  "https://app.hienergy.ai/api/v1/deals?page=2&per_page=500&include_total=true"
Response Shape
{
  "deals": {
    "data": [
      {
        "id": "532",
        "type": "deal",
        "attributes": {
          "title": "NordVPN Deal",
          "country_list": ["us"],
          "exclusive": true,
          "deal_kind": "coupon",
          "deal_kind_label": "Coupon"
        }
      }
    ]
  },
  "meta": {
    "current_page": 1,
    "next_page": 2,
    "prev_page": null,
    "per_page": 500,
    "total_count": null,
    "total_pages": null
  }
}
Note: max 500 per page. After deal_kind mapping changes, run rake searchkick:reindex CLASS=Deal.

GET /api/v1/advertisers

GET /api/v1/advertisers GET

Search affiliate programs by brand, domain, network, country, vertical, or status. By default this endpoint now returns Pagy-style offset pagination in meta; if you explicitly send cursor, it falls back to the compatibility cursor response.

Two live response modes: default list and search requests return data plus meta. Explicit cursor requests return data plus pagination.
Parameters
Parameter Type Description Example
Pagination
limit integer Upper bound on page size. When page/per_page are omitted, the controller still uses offset pagination by default. 10
page, per_page integer Preferred pagination controls for default advertiser listing and search. page=2&per_page=25
cursor string Compatibility pagination mode for clients that already consume advertiser cursors. Base64 cursor
Search & Filters
q, query, name string Free-form advertiser lookup. q is the preferred general-purpose search input. nike
domain, url string Website-driven lookup on the main index endpoint. Use the dedicated domain endpoint when that is your primary workflow. notion.so
network, network_slug string Filter by network name or slug. impact
country string Country availability filter. US
vertical string Filter by vertical tag name or label. Sports
status, with_deals string/boolean Filter to specific approval states or advertisers that currently have deals. approved, true
Searchkick-only Sorting
sort_by, sort_order string Supported sort fields are updated_at, deals_count, and name. This path depends on Searchkick-backed advertiser search. updated_at, desc
Agent-Friendly
dry_run boolean Inspect request wiring and response shape without relying on a live result set. true
AEO-Friendly Examples
Find the affiliate program for a brand someone named
curl -H "X-Api-Key: YOUR_KEY" \
  "https://app.hienergy.ai/api/v1/advertisers?q=nordpass&limit=5"

Use this when the user starts with a brand or product name.

Find the program from a website
curl -H "X-Api-Key: YOUR_KEY" \
  "https://app.hienergy.ai/api/v1/advertisers/search_by_domain?domain=nordpass.com&limit=5"

This is the best answer-engine path when you have a site URL or root domain.

Filter to approved US programs with deals
curl -H "X-Api-Key: YOUR_KEY" \
  "https://app.hienergy.ai/api/v1/advertisers?status=approved&country=US&with_deals=true&limit=25"
Use compatibility cursor mode only when you need it
curl -H "X-Api-Key: YOUR_KEY" \
  "https://app.hienergy.ai/api/v1/advertisers?limit=10&cursor=BASE64_CURSOR"
Default Response Shape
{
  "data": [
    {
      "id": 1,
      "attributes": {
        "name": "NordPass",
        "domain": "nordpass.com",
        "status": "approved",
        "country_list": ["us"],
        "vertical_list": ["security"]
      }
    }
  ],
  "meta": {
    "current_page": 1,
    "next_page": 2,
    "prev_page": null,
    "per_page": 25,
    "total_count": 500,
    "total_pages": 20
  }
}
Cursor Compatibility Response
{
  "data": [
    {
      "id": 1,
      "attributes": {
        "name": "NordPass"
      }
    }
  ],
  "pagination": {
    "limit": 10,
    "has_next_page": true,
    "next_cursor": "eyJpZCI6MTIzLCJjcmVhdGVkX2F0IjoiMjAyNi0wNC0wNlQxMjozMDowMFoifQ=="
  }
}
Domain endpoint behavior matches the main index: /api/v1/advertisers/search_by_domain also uses Pagy meta by default and only returns pagination when you explicitly pass cursor.

GET /api/v1/transactions

GET /api/v1/transactions GET

Retrieve affiliate transaction data with date, advertiser, network, and currency filters. The live v1 endpoint paginates with page, per_page, or limit and returns pagination data in meta.

Search-backed endpoint: transaction filtering and ordering run through TransactionsSearchkickService, then records are reloaded from Postgres in result order.
Parameters
Parameter Type Description Example
Pagination
limit integer Alias for page size. Defaults to 20 and clamps to 500. 25
page, per_page integer Preferred pagination controls for analytics or exports where you want stable page numbers. page=2&per_page=100
Filters
advertiser_id, advertiser_slug string Filter by advertiser id or slug. test-advertiser
network_id, network_slug string Filter by network id or slug. flexoffers
start_date, end_date date ISO 8601 date filters. 2026-04-01
currency string Filter by transaction currency. USD
Sorting
sort_by, sort_order string Supported sort fields are transaction_date, commission_amount, and sale_amount. Sort order is asc or desc. commission_amount, desc
Agent-Friendly
dry_run, include_total boolean Use dry_run=true to test wiring and include_total=true when you need exact totals in meta. true
AEO-Friendly Examples
Answer “show me this month’s transactions”
curl -H "X-Api-Key: YOUR_KEY" \
  "https://app.hienergy.ai/api/v1/transactions?start_date=2026-04-01&end_date=2026-04-30&per_page=100"
Answer “what are my highest-commission transactions?”
curl -H "X-Api-Key: YOUR_KEY" \
  "https://app.hienergy.ai/api/v1/transactions?sort_by=commission_amount&sort_order=desc&limit=50"
Investigate one advertiser’s performance
curl -H "X-Api-Key: YOUR_KEY" \
  "https://app.hienergy.ai/api/v1/transactions?advertiser_id=test-advertiser&start_date=2026-04-01&end_date=2026-04-30&include_total=true"
Response Shape
{
  "transactions": {
    "data": [
      {
        "id": "123",
        "type": "transaction",
        "attributes": {
          "transaction_date": "2026-04-06",
          "sale_amount": 100.0,
          "commission_amount": 10.0,
          "currency": "USD"
        }
      }
    ]
  },
  "meta": {
    "current_page": 1,
    "next_page": 2,
    "prev_page": null,
    "per_page": 100,
    "total_count": null,
    "total_pages": null
  }
}
Compatibility note: although the controller still permits a cursor param, the live v1 transactions response uses offset-style meta pagination. New clients should use page, per_page, and limit.

Contacts API

Search contacts by domain, advertiser_id, advertiser_name, or email. Create contacts (admin only). JSON:API-style responses with pagination.

View full documentation

Publishers API

View and update the publisher you are authorized to access, including name, domain, and all network API keys and credentials.

View full documentation

Status Changes API

Search status changes (advertiser approval, applied, rejected, etc.) with Searchkick. Results are scoped by your publisher.

View full documentation

Link Builder API

Generate affiliate tracking links for any URL. POST a destination URL and receive a ready-to-use affiliate tracking link. Supports Awin, CJ, Impact, Rakuten, Partnerize, Pepperjam, and Avantlink. Requires paid publisher with link generator enabled or admin access.

View full documentation

Hi Energy AI API v1

Built for AI workflows: use X-Api-Key, start with /api/v1/tools or /api/v1/schema, and expect consistent JSON envelopes plus endpoint-specific pagination metadata.
What AI Clients Should Expect
Preferred Auth

Prefer X-Api-Key for agents, MCP clients, and server-to-server integrations. Authorization: Bearer still works when you already manage an Auth0 user token.

Mixed Pagination

Most v1 list endpoints return meta.current_page, next_page, and per_page. Advertisers also support explicit cursor compatibility when you send cursor.

Structured Errors

Error responses include machine-readable codes and human-readable messages so agents can retry, recover, or explain failures cleanly.

Tool Discovery

Use /api/v1/tools for a machine-readable tool catalog and /api/v1/schema for the OpenAPI-style contract before generating calls.

MCP Support

The same authenticated API surface is also available through /mcp for tool-based AI assistants and Responses API integrations.

Dry Run

Add ?dry_run=true when you want to validate request wiring or inspect response shape before using live data.

AI Quick Start
1. Discover tools first
curl -H "X-Api-Key: YOUR_KEY" https://app.hienergy.ai/api/v1/tools Try
2. Fetch the schema when you need exact fields
curl -H "X-Api-Key: YOUR_KEY" https://app.hienergy.ai/api/v1/schema Try
3. Find programs from a brand name
curl -H "X-Api-Key: YOUR_KEY" "https://app.hienergy.ai/api/v1/advertisers?q=nordvpn&limit=5" Try
4. Find programs from a website
curl -H "X-Api-Key: YOUR_KEY" "https://app.hienergy.ai/api/v1/advertisers/search_by_domain?domain=nordvpn.com&limit=5" Try
5. List active US deals
curl -H "X-Api-Key: YOUR_KEY" "https://app.hienergy.ai/api/v1/deals?active=true&country=US&limit=25" Try
6. Inspect transactions with page-based pagination
curl -H "X-Api-Key: YOUR_KEY" "https://app.hienergy.ai/api/v1/transactions?page=1&per_page=25" Try
Answer-Engine Friendly Recipes
Find the best advertiser match

Use a short brand query first, then fetch details only for the best hit.

GET /api/v1/advertisers?q=canva&limit=5
GET /api/v1/advertisers/{id}
Answer “does this site have a program?”

Start with domain search because it is the most direct website-driven lookup.

GET /api/v1/advertisers/search_by_domain?domain=notion.so
Answer “show me active US deals”

Use deals with country plus active filters and rely on meta.next_page when paging.

GET /api/v1/deals?active=true&country=US&page=1&per_page=500
Answer “what happened this month?”

Use transactions with a date range and explicit page size for analytics workflows.

GET /api/v1/transactions?start_date=2026-04-01&end_date=2026-04-30&per_page=100
Legacy vs v1
Feature Legacy API v1 API
Authentication ?api_key= commonly used X-Api-Key preferred, bearer supported, query param still accepted for compatibility
Pagination Offset with page and per_page Mostly offset/meta; advertisers also support explicit cursor compatibility
Discovery Manual docs /api/v1/tools, /api/v1/schema, and /mcp
Error Format Less structured Consistent structured JSON with machine-readable codes

GET /api/v1/tools

GET /api/v1/tools GET

Discover available API tools and their schemas for agent integration. This endpoint provides machine-readable tool definitions that AI agents can use to understand available operations, including report discovery tools like list_reports and get_report.

Agent-Friendly: This endpoint provides JSON Schema definitions for each tool, making it easy for AI agents to understand and use the API.
Example Request
curl -H "X-Api-Key: YOUR_KEY" https://app.hienergy.ai/api/v1/tools Try

Start here when your agent needs to inspect the published tool catalog before making calls.

Response Format
{
  "tools": [
    {
      "name": "list_reports",
      "description": "List accessible JSON reports backed by materialized views, including major aliases with guidance about when to use each report.",
      "parameters": {
        "type": "object",
        "properties": {}
      },
      "endpoint": "/api/v1/reports",
      "method": "GET"
    }
  ],
  "api_version": "v1",
  "base_url": "https://app.hienergy.ai",
  "authentication": {
    "type": "multi",
    "preferred_for_agents": "api_key",
    "preferred_header": "X-Api-Key",
    "fallback_for_oauth_apps": "oauth_bearer",
    "fallback_for_legacy_clients": "api_key_query_param"
  },
  "pagination": {
    "type": "mixed",
    "description": "Most v1 list endpoints return meta pagination. Advertisers also support explicit cursor compatibility when cursor is provided."
  },
  "idempotency": {
    "header": "Idempotency-Key",
    "description": "Include Idempotency-Key header for mutating requests"
  },
  "dry_run": {
    "parameter": "dry_run",
    "description": "Add ?dry_run=true to test requests without making changes"
  }
}
Available Tools
Report selection workflow: Agents should call list_reports first when the user asks for a report and the exact report family is unclear, then fetch rows with get_report or a named report tool like get_top_advertisers_by_sales_report, get_deals_summary_report, get_status_counts_report, get_status_cards_counts_report, get_network_daily_transaction_totals_report, or get_commission_drops_month_over_month_report. For search tasks, inspect the endpoint-specific pagination notes instead of assuming every endpoint uses the same response shape.
list_reports

List major report aliases plus accessible raw materialized-view reports

GET /api/v1/reports
get_report

Fetch a report by major alias or raw materialized-view name

GET /api/v1/reports/{id}
get_top_advertisers_by_sales_report

Fetch the top advertisers leaderboard for a reporting period

GET /api/v1/reports/top_advertisers_by_sales
get_daily_kpi_totals_report

Fetch day-by-day KPI trend data for a reporting period

GET /api/v1/reports/daily_kpi_totals
search_advertisers

Search for advertisers by various criteria

GET /api/v1/advertisers
search_advertisers_by_domain

Search advertisers using the advertiser domain lookup endpoint

GET /api/v1/advertisers/search_by_domain
get_advertiser

Get detailed information about a specific advertiser

GET /api/v1/advertisers/{id}
get_similar_advertisers

Get similar advertisers for a specific advertiser

GET /api/v1/advertisers/{id}/similar_advertisers
get_related_advertisers

Get related advertisers by domain and tag signals

GET /api/v1/advertisers/{id}/related_advertisers
list_opportunities

List opportunity advertisers for the current user scope

GET /api/v1/opportunities
search_transactions

Search for transactions with filtering options

GET /api/v1/transactions
search_deals

Search for deals with filtering options

GET /api/v1/deals
search_domains

Search for advertisers by domain

GET /api/v1/domains/search
get_verticals

Get list of available verticals/industries

GET /api/v1/verticals
create_referred_user

Create a user and attribute referral to API caller

POST /api/v1/users
create_contact

Create a contact for an advertiser (admin only)

POST /api/v1/contacts
add_contact

Add a contact for an advertiser through the dedicated alias endpoint (admin only)

POST /api/v1/contacts/add
Perfect for AI Agents: This endpoint provides everything an AI agent needs to understand and use the API programmatically.

POST /mcp

The Hi Energy AI MCP server gives AI assistants and agent frameworks a dedicated Model Context Protocol endpoint backed by the same authenticated API surface as your existing REST integration.

Visit the dedicated MCP page for connection steps, JSON-RPC examples, discovery resources, and guidance for accessing both /api/v1 and legacy /api endpoints through the generic api_request bridge.

View MCP server documentation

GET /api/v1/schema

GET /api/v1/schema GET

Get the complete OpenAPI 3.0 schema for the Hi Energy AI API. This provides machine-readable documentation that can be used by API clients, documentation generators, and AI agents.

OpenAPI 3.0: This endpoint returns a complete OpenAPI specification that can be imported into tools like Postman, Insomnia, or used to generate client SDKs. It also includes agent guidance about which authentication method to prefer.
Example Request
curl -H "X-Api-Key: YOUR_KEY" https://app.hienergy.ai/api/v1/schema Try
Schema Structure
{
  "openapi": "3.0.3",
  "info": {
    "title": "Hi Energy AI API",
    "description": "Agent-friendly API for affiliate marketing data. AI agents should prefer X-Api-Key for authentication...",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://app.hienergy.ai/api/v1",
      "description": "Production server"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    },
    {
      "OAuthBearer": []
    }
  ],
  "x-agentAuthentication": {
    "preferred": "ApiKeyAuth",
    "preferredHeader": "X-Api-Key",
    "fallback": ["OAuthBearer"],
    "legacy": "api_key query parameter"
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Api-Key"
      },
      "OAuthBearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    },
    "schemas": {
      "Advertiser": { ... },
      "Transaction": { ... },
      "Deal": { ... },
      "ReportMetadata": { ... },
      "Error": { ... },
      "Pagination": { ... }
    }
  },
  "paths": {
    "/advertisers": { ... },
    "/transactions": { ... },
    "/deals": { ... },
    "/reports": { ... },
    "/tools": { ... }
  }
}
Use Cases
Import to Tools

Import the schema into Postman, Insomnia, or other API testing tools

Generate SDKs

Use OpenAPI generators to create client SDKs in various languages

AI Agent Integration

AI agents can parse the schema to understand available operations

Schema Features
  • Complete API Coverage: All endpoints, parameters, and response schemas
  • Authentication: Security schemes, requirements, and agent guidance about preferred auth methods
  • Error Handling: Structured error responses with codes
  • Pagination: Cursor-based pagination schemas
  • Rate Limiting: Rate limit headers and responses
  • Examples: Request and response examples
Standards Compliant: This schema follows OpenAPI 3.0 specifications and can be used with any compatible tool or library.
Agent Tip: If you are building an AI client, read x-agentAuthentication first, prefer X-Api-Key, then inspect /api/v1/tools to discover the current tool surface.

Pagination

Pagination varies by endpoint: most v1 list endpoints return offset-style meta. Advertisers also support an explicit cursor compatibility mode when you provide cursor.
Endpoint Matrix
Endpoint Default Pagination Response Keys Notes
/api/v1/deals Offset-style meta.current_page, next_page, per_page Default page size is 500, max 500
/api/v1/transactions Offset-style meta.current_page, next_page, per_page limit acts as a page-size alias
/api/v1/advertisers Offset-style meta.current_page, next_page, per_page Switches to pagination.next_cursor only when cursor is present
/api/v1/advertisers/search_by_domain Offset-style meta.current_page, next_page, per_page Same compatibility cursor behavior as the main advertisers index
/api/... legacy endpoints Offset-style meta.current_page, next_page, per_page Use when maintaining existing integrations
Default Offset Pagination
Recommended For Most New Clients

Use page and per_page when you want explicit navigation, or just limit when you only need to cap page size.

GET /api/v1/deals?page=1&per_page=500
GET /api/v1/transactions?limit=50
GET /api/v1/advertisers?page=2&per_page=25
{
  "meta": {
    "current_page": 1,
    "next_page": 2,
    "prev_page": null,
    "per_page": 500,
    "total_count": null,
    "total_pages": null
  }
}
Advertiser Cursor Compatibility
Available Only When You Send cursor

The advertisers endpoints still support cursor pagination for existing clients that already consume advertiser cursors.

GET /api/v1/advertisers?limit=10&cursor=BASE64_CURSOR
GET /api/v1/advertisers/search_by_domain?domain=nike.com&cursor=BASE64_CURSOR
{
  "pagination": {
    "limit": 10,
    "has_next_page": true,
    "next_cursor": "eyJpZCI6MTIzLCJjcmVhdGVkX2F0IjoiMjAyNi0wNC0wNlQxMjozMDowMFoifQ=="
  }
}
Practical AI Examples
Python
def iter_deals(session, api_key):
    page = 1
    while True:
        response = session.get(
            "https://app.hienergy.ai/api/v1/deals",
            headers={"X-Api-Key": api_key},
            params={"page": page, "per_page": 500, "active": "true"}
        )
        payload = response.json()
        yield from payload["deals"]["data"]
        if not payload["meta"]["next_page"]:
            break
        page = payload["meta"]["next_page"]
JavaScript
async function listAdvertisers(apiKey) {
  const params = new URLSearchParams({ page: 1, per_page: 25, q: "notion" });
  const response = await fetch(
    `https://app.hienergy.ai/api/v1/advertisers?${params}`,
    { headers: { "X-Api-Key": apiKey } }
  );
  const payload = await response.json();
  return {
    records: payload.data,
    nextPage: payload.meta.next_page
  };
}
Recommendation: new clients should treat offset-style meta pagination as the default contract and use advertiser cursors only when they explicitly need backward compatibility with an older advertiser integration.

Rate Limiting

Rate Limiting: Rate limits depend on your publisher. Hi Energy users: 1,000 requests per hour. Other publishers: 10,000 requests per hour. Rate limit information is included in every response via headers.
Rate Limits by Publisher
Hi Energy

1,000

requests per hour

Other publishers

10,000

requests per hour

Rate Limit Headers
Response Headers

Every API response includes rate limit information in the headers:

Header Description Example
X-RateLimit-Limit Maximum requests allowed per hour (varies by publisher) 1000 or 10000
X-RateLimit-Remaining Remaining requests in current hour 999
X-RateLimit-Reset Unix timestamp when rate limit resets 1642248000
Rate Limit Exceeded
429 Too Many Requests

When rate limited, you'll receive a 429 status with additional headers:

Header Description Example
Retry-After Seconds to wait before retrying (until next hour) 3600
X-RateLimit-Limit Rate limit per hour 1000
X-RateLimit-Remaining Remaining requests (will be 0) 0
X-RateLimit-Reset Unix timestamp when rate limit resets 1642248000
Error Response Example
{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Limit: 1000 requests per hour.",
    "retry_after": 3600,
    "timestamp": "2024-01-15T10:30:00Z",
    "request_id": "req_123456789"
  }
}

Message shows your limit (1,000 for Hi Energy, 10,000 for other publishers).

Handling Rate Limits
Python Example
import requests
import time

def make_api_request(url, headers):
    response = requests.get(url, headers=headers)

    if response.status_code == 429:
        retry_after = int(response.headers.get('Retry-After', 3600))
        print(f"Rate limited. Waiting {retry_after} seconds...")
        time.sleep(retry_after)
        return make_api_request(url, headers)  # Retry

    return response.json()

# Usage
headers = {"X-Api-Key": "your_key"}
data = make_api_request(url, headers)
JavaScript Example
async function makeApiRequest(url, headers) {
    const response = await fetch(url, { headers });

    if (response.status === 429) {
        const retryAfter = response.headers.get('Retry-After') || 3600;
        console.log(`Rate limited. Waiting ${retryAfter} seconds...`);

        await new Promise(resolve =>
            setTimeout(resolve, retryAfter * 1000)
        );

        return makeApiRequest(url, headers); // Retry
    }

    return response.json();
}

// Usage
const headers = { 'X-Api-Key': 'your_key' };
const data = await makeApiRequest(url, headers);
Best Practices
Respect Retry-After

Wait for the specified time before retrying

Monitor Usage

Track X-RateLimit-Remaining to avoid hitting the limit

Implement Backoff

Use exponential backoff for retries

Fair Usage: Rate limits ensure all users get fair access to the API while maintaining system performance.

Error Handling

Structured Error Responses: All API v1 endpoints return consistent error formats with machine-readable codes and detailed information.
Error Response Format
Standard Error Envelope
{
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable error message",
    "timestamp": "2024-01-15T10:30:00Z",
    "request_id": "req_123456789",
    "details": {
      "additional": "context information"
    }
  }
}
Common Error Codes
HTTP Status Error Code Description Example
401 UNAUTHORIZED Invalid or missing API credentials Missing X-Api-Key header
400 BAD_REQUEST Invalid request parameters Invalid date format
400 MISSING_PARAMETER Required parameter missing Missing required field
400 INVALID_PARAMETER Parameter value is invalid Limit exceeds maximum
404 NOT_FOUND Resource not found Advertiser ID doesn't exist
403 UPGRADE_REQUIRED Subscription upgrade required Free plan limitation
429 RATE_LIMIT_EXCEEDED Rate limit exceeded Too many requests
500 INTERNAL_SERVER_ERROR Unexpected server error Database connection issue
MCP (POST /mcp) JSON-RPC errors

The MCP endpoint speaks JSON-RPC 2.0. Unlike /api/v1, many failures are expressed as an error object in the JSON body (often with HTTP 400). See the MCP documentation for runnable examples.

Code Meaning Typical causes
-32700 Parse error Request body is not valid JSON.
-32600 Invalid Request Missing jsonrpc: "2.0", batch/array payload, or malformed envelope.
-32601 Method not found Unknown JSON-RPC method (not initialize, ping, tools/list, etc.).
-32602 Invalid params Missing tool name, missing resource uri, unknown resource URI, or invalid arguments shape.
Tool-level errors: Curated tools often return HTTP 200 with result.isError: true and details under result.structuredContent so clients can render a structured failure without treating transport as broken. Ping: ping returns result: {}. Protocol negotiation: unsupported initialize.protocolVersion values fall back to the server's newest supported version.
Error Examples
Authentication Error
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid or missing API credentials",
    "timestamp": "2024-01-15T10:30:00Z",
    "request_id": "req_123456789"
  }
}
Validation Error
{
  "error": {
    "code": "INVALID_PARAMETER",
    "message": "Limit must be between 1 and 50",
    "timestamp": "2024-01-15T10:30:00Z",
    "request_id": "req_123456789",
    "details": {
      "parameter": "limit",
      "value": 150,
      "constraints": {
        "min": 1,
        "max": 50
      }
    }
  }
}
Error Handling Best Practices
Check Status Codes

Always check HTTP status codes before processing response data

Use Error Codes

Use the machine-readable error codes for programmatic handling

Log Request IDs

Include request_id in error logs for debugging

Retry Logic

Implement retry logic for rate limit and server errors

Python Error Handling Example
Python Example
import requests
import time

def handle_api_error(response):
    if response.status_code == 200:
        return response.json()

    error_data = response.json()
    error_code = error_data['error']['code']
    request_id = error_data['error']['request_id']

    if error_code == 'RATE_LIMIT_EXCEEDED':
        retry_after = response.headers.get('Retry-After', 60)
        print(f"Rate limited. Retrying after {retry_after} seconds...")
        time.sleep(int(retry_after))
        return None  # Retry the request

    elif error_code == 'UNAUTHORIZED':
        print("Authentication failed. Check your API key.")
        return None

    elif error_code == 'UPGRADE_REQUIRED':
        print("Subscription upgrade required.")
        return None

    else:
        print(f"API Error: {error_code} - {error_data['error']['message']}")
        print(f"Request ID: {request_id}")
        return None

# Usage
response = requests.get(url, headers=headers)
result = handle_api_error(response)
Consistent Format: All error responses follow the same structure, making it easy to build robust error handling in your applications.

Commission Rates

Commission Rate Fields Data Fields

Commission rate information is available in the advertiser show API response. These fields provide detailed commission rate data including network defaults, actual rates, and calculated averages.

Commission Rate Data: These fields are returned as part of the advertiser show API response and provide comprehensive commission rate information for each advertiser.

Commission Rate Fields

The advertiser show API includes detailed commission rate information organized into three main categories. Below is a comprehensive list of all commission rate fields returned in the response:

Network Commission Rates
Field Nullable Type Description
network_default_commission Yes Float The default commission rate set by the network for this advertiser (Note: Advertisers may have multiple default rates)
network_max_commission Yes Float The maximum commission rate available from the network
network_min_commission Yes Float The minimum commission rate available from the network
commission_summary Yes String A summary description of the commission structure
Actual Commission Rates
Proprietary Data: These rates are calculated from our proprietary data collected from several hundred publishers across multiple affiliate networks.
Field Nullable Type Description
average_commission_rate Yes Float The average commission rate across all transactions
default_commission_rate Yes Float The default commission rate for this advertiser
max_commission_rate Yes Float The maximum commission rate achieved
median_commission_rate Yes Float The median commission rate across all transactions
min_commission_rate Yes Float The minimum commission rate achieved
Primary Commission Rate Deprecated
Field Nullable Type Description
commission_rate Yes Float The primary commission rate used for display and calculations. Falls back to network_default_commission, then commission_rate, then average_commission_rate Deprecated
Example Response
Commission Rate Data in Advertiser Response
{
"id": 123,
"name": "Example Brand",
"url": "https://example.com",
"domain": "example.com",
"status": "approved",
"network_commission_rates": {
  "network_default_commission": 5.0,
  "network_max_commission": 8.0,
  "network_min_commission": 3.0,
  "commission_summary": "Standard commission structure"
},
"actual_commission_rates": {
  "average_commission_rate": 5.2,
  "commission_rate": 5.0,
  "default_commission_rate": 5.0,
  "max_commission_rate": 7.5,
  "median_commission_rate": 5.1,
  "min_commission_rate": 3.2
},
"commission_rate": 5.0
}
Usage Notes
  • Network Commission Rates: These represent the rates set by the affiliate network for this advertiser. Note that advertisers may have multiple default rates.
  • Actual Commission Rates: These are calculated from our proprietary data collected from several hundred publishers across multiple affiliate networks
  • Primary Commission Rate: The main rate used for display, with intelligent fallback logic Deprecated
  • Rate Calculations: Average and median rates are calculated from our proprietary transaction data across hundreds of publishers
  • Fallback Logic: Primary rate uses network_default_commission → commission_rate → average_commission_rate
  • Data Freshness: Rates are updated based on recent transaction data and network changes
  • Null Values: Some rates may be null if insufficient data is available for calculation

Legacy API

Legacy API: The original API endpoints remain fully functional for backward compatibility. All existing integrations will continue to work without changes.
Migration Guide
From Legacy to Agent-Friendly API
Feature Legacy API Agent-Friendly v1 Migration Action
Authentication ?api_key= X-Api-Key: header Optional Both supported
Base URL /api/ /api/v1/ Required Update URLs
Pagination page, per_page Mostly page/per_page or limit; advertisers also support explicit cursor compatibility Optional v1 keeps offset pagination and adds advertiser cursor compatibility
Error Format {"error": "message"} Structured with codes Required Update error handling
Rate Limiting Basic headers Full headers + Retry-After Optional Enhanced headers
Tool Discovery Manual docs /tools endpoint New Use for agents
Schema Manual docs /schema endpoint New Use for clients
Dry Run Not available ?dry_run=true New Use for testing
Legacy API Endpoints
GET /api/advertisers

Search advertisers with offset pagination

Offset-based pagination
GET /api/advertisers/:id

Get advertiser details

Single resource
GET /api/domains/search

Search by domain

Domain lookup
Migration Examples
Before (Legacy)
# Legacy API call
curl "https://app.hienergy.ai/api/advertisers?page=2&per_page=10&api_key=YOUR_KEY"

# Legacy error handling
if response.status_code != 200:
    error = response.json()
    print(error["error"])  # Simple string
After (Agent-Friendly)
# Agent-friendly API call
curl -H "X-Api-Key: YOUR_KEY" \
     "https://app.hienergy.ai/api/v1/advertisers?page=1&per_page=10"

# Optional advertiser cursor compatibility
curl -H "X-Api-Key: YOUR_KEY" \
     "https://app.hienergy.ai/api/v1/advertisers?limit=10&cursor=NEXT_CURSOR"

# Agent-friendly error handling
if response.status_code != 200:
    error = response.json()
    print(f"{error['error']['code']}: {error['error']['message']}")
    print(f"Request ID: {error['error']['request_id']}")
Response Format Comparison
Legacy Response
{
  "data": [...],
  "meta": {
    "current_page": 2,
    "next_page": 3,
    "prev_page": 1,
    "total_pages": 100,
    "total_count": 1000,
    "per_page": 10
  }
}
Agent-Friendly Response
{
  "data": [...],
  "meta": {
    "current_page": 1,
    "next_page": 2,
    "prev_page": null,
    "per_page": 10,
    "total_count": 51,
    "total_pages": 6
  }
}
Migration Timeline
Now
Both APIs Available: Legacy and agent-friendly APIs work simultaneously
Phase 1
Gradual Migration: Start using v1 API for new features and integrations
Phase 2
Update Existing: Migrate existing integrations to v1 API
Future
Legacy Support: Legacy API will continue to be supported indefinitely
No Rush: Take your time migrating. The legacy API will continue to work, and you can migrate at your own pace.