Skip to main content

Hex API

Programmatically run Hex projects with the API.

info

Available on the Team and Enterprise plans.

Not currently available for HIPAA compliant workspaces (hosted at https://hc.hex.tech)

The Hex public API provides a way to trigger runs of published Hex projects. If you are looking to trigger these runs from an orchestrator, check out the Hex-managed Airflow and Dagster integrations, or the vendor-managed Shipyard integration. For path parameters and schema of specific endpoints, view the API reference.

Authentication

API Requests are authenticated using Oauth 2.0 Bearer Tokens in the header of the HTTP request. The token is always bound to a single Hex user's account and requests are executed as that Hex user, meaning the user can only execute requests against projects that are in line with the current permissions for that project.

Token creation

There are two types of tokens users can create: Personal access tokens and Workspace tokens.

Personal access tokens

Personal access tokens mirror the same permissions that a user has within the Hex product. They can be created by anyone with an Editor or higher workspace role. Unlike workspace tokens (which can have no expiration), they must be configured to expire after a fixed duration.

info

Enforcing token expiration for personal access tokens ensures that tokens are rotated frequently.

To create a Personal access token, head to the API keys page, under the Account section. Then, select the New Token button and provide a description and an expiration time frame. An existing token can be regenerated at any time by selecting the three-dot menu to the right of the token, and selecting Regenerate.

warning

Regenerating a personal access token will generate a new value for the token and immediately revoke the existing token.

If a user is deactivated in a workspace, their personal access tokens will no longer work.

Workspace tokens

Workspace tokens are created, managed, and shared by Admins of a workspace. Unlike personal access token, workspace tokens can be configured to never expire. This more permissive setting is available for workspace tokens, since any Admin can revoke this token at any time.

To create a Workspace token, head to the API keys page, under the Account section. Then, select the New Token button and provide a description and an expiration time frame. Workspace tokens can be configured to have the following scopes:

  • Read only: The token will work with any API endpoint that only gets information (e.g. ListProjects and GetProjectRuns).
  • Run projects: The token will also work with the RunProjects endpoint.
tip

If you are creating a token that is used to orchestrate projects across a workspace, consider using a Workspace token so that the token is not scoped to an individual user.

Comparison

FeaturePersonal access tokenWorkspace token
Required workspace roleEditor or higherAdmin only
Maximum expirationFollows expiration rules configured by AdminsCan be configured to never expire
PermissionsMirrors an individual user's permissionsMirrors the admin permissions for the workspace, with additional configuration for scopes

Token expiration

When creating a token, users can specify an expiration period:

  • Personal access tokens: When creating a personal access token, users can specify a time to live that is equal to, or less than, the maximum expiration time configured by an Admin (see below). Durations may include 7, 30, 60, 90, or 120 days.
  • Workspace tokens: When creating a workspace token, admins can specify an expiration that is a fixed duration (one of 7, 30, 60, 90, or 120 days), or no expiry.

To configure the maximum expiration for a personal access token, Admins can head to the Integrations page, under the Workspace section of Settings.

Users will receive an email notification 72 hours before and 24 hours before any token expires, warning them that the token will be expiring soon. Tokens can be manually revoked by clicking the three-dot menu to the right of the token, and selecting Revoke. Once a token is revoked or expired, the token can never again be used to authenticate requests.

Using the API

The Hex API allows users to programmatically run published Hex projects. This makes it simple to run projects with specific inputs, and allows for automation of workflows that update cached query results and the cached state of an app. The full reference docs for the API can be found here.

The below examples use the requests package to run the API, though the API can be invoked by many other methods (e.g. running a cURL command).

Setup needed for the API

To use the API correctly, first run some setup code. Ensure that you replace values for your specific use-case.

  • Base URL: For most Hex users, this will be https://app.hex.tech/api/v1. Single-tenant app users should replace the app.hex.tech part of this URL with the URL they use to access Hex (e.g. atreides.hex.tech).
  • Project ID: The project ID can be found by visiting the project you wish to run, and copying it from the URL — the ID is the part of the URL after the /hex/. Additionally, the project ID can be found in the Variables view of the sidebar.
  • Token: See the above section on token creation. Consider using a secret to store this more securely.
import requests

# Single tenant users will need to replace this with their Hex URL
BASE_URL = 'https://app.hex.tech/api/v1'

# Replace this with the project ID
PROJECT_ID = '5a8591dd-4039-49df-9202-96385ba3eff8'

# Replace this with your token
TOKEN = '5bbf1c8b1989d6657d5c'

Run a published project with default inputs

This API call uses the RunProject endpoint to run a published project with its default inputs. It does not update the cache for this project.

response = requests.post(
url=f"{BASE_URL}/project/{PROJECT_ID}/run",
headers={"Authorization" : f"Bearer {TOKEN}"}
)

The response from this request will contain a runUrl which will display the results of the project run as a Snapshot, viewable by any user who has at least view access to the project.

Run a published project with custom inputs

The RunProject endpoint contains an optional inputParams body parameter that allows users to specify the values for Input parameters to be used in the project run.

inputs = {
"inputParams": {
"user_name": "j_doe",
"team": "finance",
"id": 1234567890
}
}

response = requests.post(
url=f"{BASE_URL}/project/{PROJECT_ID}/run",
json=inputs,
headers={"Authorization" : f"Bearer {TOKEN}"}
)

Update the cached state and query cache of a published project

When updateCache is set to true in a RunProject request, the project run can refresh the cached state displayed for users when the published app is opened, as well as the cached results of SQL queries.

In order to update the cached state of the published app, cache default state must be enabled. If inputParams are included in the request when updateCache is set to true, the Input parameter values will be ignored. This is because updating the published app’s cache state requires the default Input parameter values to be used.

In order for a query to execute and update cached results, query caching must be enabled, and the On scheduled run configuration option must also be enabled. If query caching is enabled and the on scheduled run option is disabled, the project run will use cached query results, if available.


inputs = {
"updateCache": "true"
}

response = requests.post(
url=f"{BASE_URL}/project/{PROJECT_ID}/run",
json=inputs,
headers={"Authorization" : f"Bearer {TOKEN}"}
)

Cancel active runs for a project

Project runs can be cancelled using the CancelRun endpoint. This can be especially useful if project runs triggered by the API are contributing to database performance degradation, or your user is running into the kernel limit. The GetProjectRuns endpoint can be used in conjunction with this in order to easily cancel all project runs.

# Get all runs for project
response = requests.get(
url=f"{BASE_URL}/project/{PROJECT_ID}/runs",
params={"limit": 25, "statusFilter": "RUNNING"},
headers={"Authorization" : f"Bearer {TOKEN}"}
)
response = response.json()

# Iterate through runs and cancel them
for run in response["runs"]:
run_id = run["runId"]
requests.delete(
url=f"{BASE_URL}/project/{PROJECT_ID}/run/{run_id}",
headers={"Authorization" : f"Bearer {TOKEN}"}
)

Kernel and rate limits

Users are limited to 60 API requests per minute. If a user exceeds 60 requests in a minute, subsequent requests will be denied and return a 429 status until the rate limit is reset, 60 seconds after the first request. Request response headers contain metadata about the remaining number of requests allowed, and when the rate limit will be reset.

Users are also limited to 25 concurrently running kernels between projects opened in the Hex UI and project runs triggered via the API. Each RunProject request will use a single kernel until the project run completes. Once 25 kernels are running, subsequent RunProject requests will result in a 503 status code, with no project run created. In addition to this, projects opened in the UI that do not already have a running kernel will show an error that you have reached the maximum number of running kernels. Cancelling a project run using the CancelRun endpoint will stop a running kernel and free it for use via the UI or API.

The API and hextoolkit

The hextoolkit contains a wrapper for all of the Hex API's functionality. This section is a brief overview of the functionality and syntax. You can view all of the ApiClient methods, their arguments, and their return objects in the API reference docs.

Create the client

To make requests using the hextoolkit, you will need to generate an ApiClient with your token. We recommend storing this token as a secret.

import hextoolkit as htk
import hex_api
api_client = htk.get_api_client(TOKEN)

Get project metadata

Metadata can be fetched for an individual project via the get_project endpoint or for up to 100 projects via the list_projects endpoint.

single_project = api_client.get_project(project_id=PROJECT_ID)
many_projects = api_client.list_projects(limit=100)

A ProjectApiResource is returned from the get_project endpoint, which contains various pieces of metadata about the project (see the API Reference docs for the complete object structure). The list_projects endpoint will return a list of these, as well as a pagination object containing cursor information for fetching the next page of projects. You can pass in the pagination.after cursor string into a subsequent list_projects() request in order to continue fetching new projects. When the end of pagination has been reached, the after value will be None. See below for an example of a loop to fetch metadata for all projects in a workspace:

first_page = client.list_projects(limit=100)
after = first_page.pagination.after
projects = first_page.values

while after:
response = client.list_projects(limit = 100, after=after)
after = response.pagination.after
new_projects = response.values
projects = [*projects, *new_projects]

Run projects

Running a project with no inputs is as simple as specifying the project_id:

project_run = api_client.run_project(project_id=PROJECT_ID)

The run_project method returns a ProjectRunResponsePayload object containing metadata, as well as a run_url where you can view the results.

It is also possible to run a project with inputs or to update the cache of a project using the run_project_request_body argument:

# Run a project with inputs
input_request_body = hex_api.RunProjectRequestBody(
input_params={
"input_parameter_name": "input_parameter_value",
...
}
)

# Set a new cache
update_cache_request_body = hex_api.RunProjectRequestBody(
update_cache=True
)

# Update the value used for run_project_request_body depending on desired behavior
project_run = api_client.run_project(project_id=PROJECT_ID, run_project_request_body=input_request_body)

Get a run status

The status of a run can be viewed using the run_status_url as part of the returned object from the run_project method. The get_run_status method can also be used to programmatically check the status of a run:

project_run = api_client.run_project(project_id=PROJECT_ID)
status = api_client.get_run_status(project_id=PROJECT_ID, run_id=project_run.run_id)

Cancel a project run

Project runs can be cancelled using the cancel_run method:

project_run = api_client.run_project(project_id=PROJECT_ID)
api_client.cancel_run(project_id=PROJECT_ID, run_id=project_run.run_id)

Get all project runs

All runs of a given project can be retrieved using the get_project_runs method. The project runs can be filtered using the status_filter argument to easily identify project runs that have completed, errored, etc.

active_runs = api_client.get_project_runs(project_id=PROJECT_ID, status_filter='RUNNING')

Troubleshooting

200 Success

A 200 status code can surface on failed requests from Hex's HIPAA compliant workspaces (hosted at https://hc.hex.tech). The Hex API isn't currently available for these workspaces.

401 Unauthorized

A 401 status code indicates that Hex was unable to authenticate the request. Make sure that a token is being included in the header of your request, and that you have specified a valid base URL. If you are including a token in the header of the request, double-check that the token has not expired and consider regenerating the token or creating a new token.

404 Not found

A 404 status code indicates that Hex was unable to find the resource referenced. This could mean that the project ID or run ID included in the request are not accurate, or that your user does not have permission for the requested resource. Double-check that the user an access the Hex project in the UI.

422 Unprocessable Entity

A 422 status code can indicate that you are attempting to interact with a project that hasn't been published, or that you have provided invalid input parameters as a part of your request. Double-check that your app has been published, and that any input parameters provided are correctly specified.

429 Too many requests

A 429 status code indicates that you have hit the request rate limit. See the section on rate limiting above for more information.

500 Internal server error

A 500 status code indicates an error with the Hex application. Please contact Hex support for help troubleshooting.

503 Service Unavailable

A 503 status code indicates that the user has reached the maximum number of concurrently running kernels. See the section on kernel limits above for more information.

ValueError: Invalid value for values, must not be None

This error can surface when an API call from the hextoolkit API client is used to make a request from a HIPAA compliant workspace (hosted at https://hc.hex.tech). The Hex API isn't currently available for these workspaces.